();
- int sizePlus1 = 1;
- int i = 0, start = 0;
- boolean match = false;
- boolean lastMatch = false;
- if (separatorChars == null) {
- // Null separator means use whitespace
- while (i < len) {
- if (Character.isWhitespace(str.charAt(i))) {
- if (match || preserveAllTokens) {
- lastMatch = true;
- if (sizePlus1++ == max) {
- i = len;
- lastMatch = false;
- }
- list.add(str.substring(start, i));
- match = false;
- }
- start = ++i;
- continue;
- }
- lastMatch = false;
- match = true;
- i++;
- }
- } else if (separatorChars.length() == 1) {
- // Optimise 1 character case
- char sep = separatorChars.charAt(0);
- while (i < len) {
- if (str.charAt(i) == sep) {
- if (match || preserveAllTokens) {
- lastMatch = true;
- if (sizePlus1++ == max) {
- i = len;
- lastMatch = false;
- }
- list.add(str.substring(start, i));
- match = false;
- }
- start = ++i;
- continue;
- }
- lastMatch = false;
- match = true;
- i++;
- }
- } else {
- // standard case
- while (i < len) {
- if (separatorChars.indexOf(str.charAt(i)) >= 0) {
- if (match || preserveAllTokens) {
- lastMatch = true;
- if (sizePlus1++ == max) {
- i = len;
- lastMatch = false;
- }
- list.add(str.substring(start, i));
- match = false;
- }
- start = ++i;
- continue;
- }
- lastMatch = false;
- match = true;
- i++;
- }
- }
- if (match || preserveAllTokens && lastMatch) {
- list.add(str.substring(start, i));
- }
- return list.toArray(new String[list.size()]);
- }
-
- /**
- * Splits a String by Character type as returned by
- * {@code java.lang.Character.getType(char)}. Groups of contiguous
- * characters of the same type are returned as complete tokens.
- *
- * StringUtils.splitByCharacterType(null) = null
- * StringUtils.splitByCharacterType("") = []
- * StringUtils.splitByCharacterType("ab de fg") = ["ab", " ", "de", " ", "fg"]
- * StringUtils.splitByCharacterType("ab de fg") = ["ab", " ", "de", " ", "fg"]
- * StringUtils.splitByCharacterType("ab:cd:ef") = ["ab", ":", "cd", ":", "ef"]
- * StringUtils.splitByCharacterType("number5") = ["number", "5"]
- * StringUtils.splitByCharacterType("fooBar") = ["foo", "B", "ar"]
- * StringUtils.splitByCharacterType("foo200Bar") = ["foo", "200", "B", "ar"]
- * StringUtils.splitByCharacterType("ASFRules") = ["ASFR", "ules"]
- *
- * @param str the String to split, may be {@code null}
- * @return an array of parsed Strings, {@code null} if null String input
- * @since 2.4
- */
- public static String[] splitByCharacterType(String str) {
- return splitByCharacterType(str, false);
- }
-
- /**
- * Splits a String by Character type as returned by
- * {@code java.lang.Character.getType(char)}. Groups of contiguous
- * characters of the same type are returned as complete tokens, with the
- * following exception: the character of type
- * {@code Character.UPPERCASE_LETTER}, if any, immediately
- * preceding a token of type {@code Character.LOWERCASE_LETTER}
- * will belong to the following token rather than to the preceding, if any,
- * {@code Character.UPPERCASE_LETTER} token.
- *
- * StringUtils.splitByCharacterTypeCamelCase(null) = null
- * StringUtils.splitByCharacterTypeCamelCase("") = []
- * StringUtils.splitByCharacterTypeCamelCase("ab de fg") = ["ab", " ", "de", " ", "fg"]
- * StringUtils.splitByCharacterTypeCamelCase("ab de fg") = ["ab", " ", "de", " ", "fg"]
- * StringUtils.splitByCharacterTypeCamelCase("ab:cd:ef") = ["ab", ":", "cd", ":", "ef"]
- * StringUtils.splitByCharacterTypeCamelCase("number5") = ["number", "5"]
- * StringUtils.splitByCharacterTypeCamelCase("fooBar") = ["foo", "Bar"]
- * StringUtils.splitByCharacterTypeCamelCase("foo200Bar") = ["foo", "200", "Bar"]
- * StringUtils.splitByCharacterTypeCamelCase("ASFRules") = ["ASF", "Rules"]
- *
- * @param str the String to split, may be {@code null}
- * @return an array of parsed Strings, {@code null} if null String input
- * @since 2.4
- */
- public static String[] splitByCharacterTypeCamelCase(String str) {
- return splitByCharacterType(str, true);
- }
-
- /**
- * Splits a String by Character type as returned by
- * {@code java.lang.Character.getType(char)}. Groups of contiguous
- * characters of the same type are returned as complete tokens, with the
- * following exception: if {@code camelCase} is {@code true},
- * the character of type {@code Character.UPPERCASE_LETTER}, if any,
- * immediately preceding a token of type {@code Character.LOWERCASE_LETTER}
- * will belong to the following token rather than to the preceding, if any,
- * {@code Character.UPPERCASE_LETTER} token.
- * @param str the String to split, may be {@code null}
- * @param camelCase whether to use so-called "camel-case" for letter types
- * @return an array of parsed Strings, {@code null} if null String input
- * @since 2.4
- */
- private static String[] splitByCharacterType(String str, boolean camelCase) {
- if (str == null) {
- return null;
- }
- if (str.length() == 0) {
- return ArrayUtils.EMPTY_STRING_ARRAY;
- }
- char[] c = str.toCharArray();
- List list = new ArrayList();
- int tokenStart = 0;
- int currentType = Character.getType(c[tokenStart]);
- for (int pos = tokenStart + 1; pos < c.length; pos++) {
- int type = Character.getType(c[pos]);
- if (type == currentType) {
- continue;
- }
- if (camelCase && type == Character.LOWERCASE_LETTER && currentType == Character.UPPERCASE_LETTER) {
- int newTokenStart = pos - 1;
- if (newTokenStart != tokenStart) {
- list.add(new String(c, tokenStart, newTokenStart - tokenStart));
- tokenStart = newTokenStart;
- }
- } else {
- list.add(new String(c, tokenStart, pos - tokenStart));
- tokenStart = pos;
- }
- currentType = type;
- }
- list.add(new String(c, tokenStart, c.length - tokenStart));
- return list.toArray(new String[list.size()]);
- }
-
- // Joining
- //-----------------------------------------------------------------------
- /**
- * Joins the elements of the provided array into a single String
- * containing the provided list of elements.
- *
- * No separator is added to the joined String.
- * Null objects or empty strings within the array are represented by
- * empty strings.
- *
- *
- * StringUtils.join(null) = null
- * StringUtils.join([]) = ""
- * StringUtils.join([null]) = ""
- * StringUtils.join(["a", "b", "c"]) = "abc"
- * StringUtils.join([null, "", "a"]) = "a"
- *
- *
- * @param the specific type of values to join together
- * @param elements the values to join together, may be null
- * @return the joined String, {@code null} if null array input
- * @since 2.0
- * @since 3.0 Changed signature to use varargs
- */
- public static String join(T... elements) {
- return join(elements, null);
- }
-
- /**
- * Joins the elements of the provided array into a single String
- * containing the provided list of elements.
- *
- * No delimiter is added before or after the list.
- * Null objects or empty strings within the array are represented by
- * empty strings.
- *
- *
- * StringUtils.join(null, *) = null
- * StringUtils.join([], *) = ""
- * StringUtils.join([null], *) = ""
- * StringUtils.join(["a", "b", "c"], ';') = "a;b;c"
- * StringUtils.join(["a", "b", "c"], null) = "abc"
- * StringUtils.join([null, "", "a"], ';') = ";;a"
- *
- *
- * @param array the array of values to join together, may be null
- * @param separator the separator character to use
- * @return the joined String, {@code null} if null array input
- * @since 2.0
- */
- public static String join(Object[] array, char separator) {
- if (array == null) {
- return null;
- }
-
- return join(array, separator, 0, array.length);
- }
-
- /**
- * Joins the elements of the provided array into a single String
- * containing the provided list of elements.
- *
- * No delimiter is added before or after the list.
- * Null objects or empty strings within the array are represented by
- * empty strings.
- *
- *
- * StringUtils.join(null, *) = null
- * StringUtils.join([], *) = ""
- * StringUtils.join([null], *) = ""
- * StringUtils.join(["a", "b", "c"], ';') = "a;b;c"
- * StringUtils.join(["a", "b", "c"], null) = "abc"
- * StringUtils.join([null, "", "a"], ';') = ";;a"
- *
- *
- * @param array the array of values to join together, may be null
- * @param separator the separator character to use
- * @param startIndex the first index to start joining from. It is
- * an error to pass in an end index past the end of the array
- * @param endIndex the index to stop joining from (exclusive). It is
- * an error to pass in an end index past the end of the array
- * @return the joined String, {@code null} if null array input
- * @since 2.0
- */
- public static String join(Object[] array, char separator, int startIndex, int endIndex) {
- if (array == null) {
- return null;
- }
- int noOfItems = endIndex - startIndex;
- if (noOfItems <= 0) {
- return EMPTY;
- }
-
- StringBuilder buf = new StringBuilder(noOfItems * 16);
-
- for (int i = startIndex; i < endIndex; i++) {
- if (i > startIndex) {
- buf.append(separator);
- }
- if (array[i] != null) {
- buf.append(array[i]);
- }
- }
- return buf.toString();
- }
-
- /**
- * Joins the elements of the provided array into a single String
- * containing the provided list of elements.
- *
- * No delimiter is added before or after the list.
- * A {@code null} separator is the same as an empty String ("").
- * Null objects or empty strings within the array are represented by
- * empty strings.
- *
- *
- * StringUtils.join(null, *) = null
- * StringUtils.join([], *) = ""
- * StringUtils.join([null], *) = ""
- * StringUtils.join(["a", "b", "c"], "--") = "a--b--c"
- * StringUtils.join(["a", "b", "c"], null) = "abc"
- * StringUtils.join(["a", "b", "c"], "") = "abc"
- * StringUtils.join([null, "", "a"], ',') = ",,a"
- *
- *
- * @param array the array of values to join together, may be null
- * @param separator the separator character to use, null treated as ""
- * @return the joined String, {@code null} if null array input
- */
- public static String join(Object[] array, String separator) {
- if (array == null) {
- return null;
- }
- return join(array, separator, 0, array.length);
- }
-
- /**
- * Joins the elements of the provided array into a single String
- * containing the provided list of elements.
- *
- * No delimiter is added before or after the list.
- * A {@code null} separator is the same as an empty String ("").
- * Null objects or empty strings within the array are represented by
- * empty strings.
- *
- *
- * StringUtils.join(null, *) = null
- * StringUtils.join([], *) = ""
- * StringUtils.join([null], *) = ""
- * StringUtils.join(["a", "b", "c"], "--") = "a--b--c"
- * StringUtils.join(["a", "b", "c"], null) = "abc"
- * StringUtils.join(["a", "b", "c"], "") = "abc"
- * StringUtils.join([null, "", "a"], ',') = ",,a"
- *
- *
- * @param array the array of values to join together, may be null
- * @param separator the separator character to use, null treated as ""
- * @param startIndex the first index to start joining from. It is
- * an error to pass in an end index past the end of the array
- * @param endIndex the index to stop joining from (exclusive). It is
- * an error to pass in an end index past the end of the array
- * @return the joined String, {@code null} if null array input
- */
- public static String join(Object[] array, String separator, int startIndex, int endIndex) {
- if (array == null) {
- return null;
- }
- if (separator == null) {
- separator = EMPTY;
- }
-
- // endIndex - startIndex > 0: Len = NofStrings *(len(firstString) + len(separator))
- // (Assuming that all Strings are roughly equally long)
- int noOfItems = endIndex - startIndex;
- if (noOfItems <= 0) {
- return EMPTY;
- }
-
- StringBuilder buf = new StringBuilder(noOfItems * 16);
-
- for (int i = startIndex; i < endIndex; i++) {
- if (i > startIndex) {
- buf.append(separator);
- }
- if (array[i] != null) {
- buf.append(array[i]);
- }
- }
- return buf.toString();
- }
-
- /**
- * Joins the elements of the provided {@code Iterator} into
- * a single String containing the provided elements.
- *
- * No delimiter is added before or after the list. Null objects or empty
- * strings within the iteration are represented by empty strings.
- *
- * See the examples here: {@link #join(Object[],char)}.
- *
- * @param iterator the {@code Iterator} of values to join together, may be null
- * @param separator the separator character to use
- * @return the joined String, {@code null} if null iterator input
- * @since 2.0
- */
- public static String join(Iterator> iterator, char separator) {
-
- // handle null, zero and one elements before building a buffer
- if (iterator == null) {
- return null;
- }
- if (!iterator.hasNext()) {
- return EMPTY;
- }
- Object first = iterator.next();
- if (!iterator.hasNext()) {
- return ObjectUtils.toString(first);
- }
-
- // two or more elements
- StringBuilder buf = new StringBuilder(256); // Java default is 16, probably too small
- if (first != null) {
- buf.append(first);
- }
-
- while (iterator.hasNext()) {
- buf.append(separator);
- Object obj = iterator.next();
- if (obj != null) {
- buf.append(obj);
- }
- }
-
- return buf.toString();
- }
-
- /**
- * Joins the elements of the provided {@code Iterator} into
- * a single String containing the provided elements.
- *
- * No delimiter is added before or after the list.
- * A {@code null} separator is the same as an empty String ("").
- *
- * See the examples here: {@link #join(Object[],String)}.
- *
- * @param iterator the {@code Iterator} of values to join together, may be null
- * @param separator the separator character to use, null treated as ""
- * @return the joined String, {@code null} if null iterator input
- */
- public static String join(Iterator> iterator, String separator) {
-
- // handle null, zero and one elements before building a buffer
- if (iterator == null) {
- return null;
- }
- if (!iterator.hasNext()) {
- return EMPTY;
- }
- Object first = iterator.next();
- if (!iterator.hasNext()) {
- return ObjectUtils.toString(first);
- }
-
- // two or more elements
- StringBuilder buf = new StringBuilder(256); // Java default is 16, probably too small
- if (first != null) {
- buf.append(first);
- }
-
- while (iterator.hasNext()) {
- if (separator != null) {
- buf.append(separator);
- }
- Object obj = iterator.next();
- if (obj != null) {
- buf.append(obj);
- }
- }
- return buf.toString();
- }
-
- /**
- * Joins the elements of the provided {@code Iterable} into
- * a single String containing the provided elements.
- *
- * No delimiter is added before or after the list. Null objects or empty
- * strings within the iteration are represented by empty strings.
- *
- * See the examples here: {@link #join(Object[],char)}.
- *
- * @param iterable the {@code Iterable} providing the values to join together, may be null
- * @param separator the separator character to use
- * @return the joined String, {@code null} if null iterator input
- * @since 2.3
- */
- public static String join(Iterable> iterable, char separator) {
- if (iterable == null) {
- return null;
- }
- return join(iterable.iterator(), separator);
- }
-
- /**
- * Joins the elements of the provided {@code Iterable} into
- * a single String containing the provided elements.
- *
- * No delimiter is added before or after the list.
- * A {@code null} separator is the same as an empty String ("").
- *
- * See the examples here: {@link #join(Object[],String)}.
- *
- * @param iterable the {@code Iterable} providing the values to join together, may be null
- * @param separator the separator character to use, null treated as ""
- * @return the joined String, {@code null} if null iterator input
- * @since 2.3
- */
- public static String join(Iterable> iterable, String separator) {
- if (iterable == null) {
- return null;
- }
- return join(iterable.iterator(), separator);
- }
-
- // Delete
- //-----------------------------------------------------------------------
- /**
- * Deletes all whitespaces from a String as defined by
- * {@link Character#isWhitespace(char)}.
- *
- *
- * StringUtils.deleteWhitespace(null) = null
- * StringUtils.deleteWhitespace("") = ""
- * StringUtils.deleteWhitespace("abc") = "abc"
- * StringUtils.deleteWhitespace(" ab c ") = "abc"
- *
- *
- * @param str the String to delete whitespace from, may be null
- * @return the String without whitespaces, {@code null} if null String input
- */
- public static String deleteWhitespace(String str) {
- if (isEmpty(str)) {
- return str;
- }
- int sz = str.length();
- char[] chs = new char[sz];
- int count = 0;
- for (int i = 0; i < sz; i++) {
- if (!Character.isWhitespace(str.charAt(i))) {
- chs[count++] = str.charAt(i);
- }
- }
- if (count == sz) {
- return str;
- }
- return new String(chs, 0, count);
- }
-
- // Remove
- //-----------------------------------------------------------------------
- /**
- * Removes a substring only if it is at the beginning of a source string,
- * otherwise returns the source string.
- *
- * A {@code null} source string will return {@code null}.
- * An empty ("") source string will return the empty string.
- * A {@code null} search string will return the source string.
- *
- *
- * StringUtils.removeStart(null, *) = null
- * StringUtils.removeStart("", *) = ""
- * StringUtils.removeStart(*, null) = *
- * StringUtils.removeStart("www.domain.com", "www.") = "domain.com"
- * StringUtils.removeStart("domain.com", "www.") = "domain.com"
- * StringUtils.removeStart("www.domain.com", "domain") = "www.domain.com"
- * StringUtils.removeStart("abc", "") = "abc"
- *
- *
- * @param str the source String to search, may be null
- * @param remove the String to search for and remove, may be null
- * @return the substring with the string removed if found,
- * {@code null} if null String input
- * @since 2.1
- */
- public static String removeStart(String str, String remove) {
- if (isEmpty(str) || isEmpty(remove)) {
- return str;
- }
- if (str.startsWith(remove)){
- return str.substring(remove.length());
- }
- return str;
- }
-
- /**
- * Case insensitive removal of a substring if it is at the beginning of a source string,
- * otherwise returns the source string.
- *
- * A {@code null} source string will return {@code null}.
- * An empty ("") source string will return the empty string.
- * A {@code null} search string will return the source string.
- *
- *
- * StringUtils.removeStartIgnoreCase(null, *) = null
- * StringUtils.removeStartIgnoreCase("", *) = ""
- * StringUtils.removeStartIgnoreCase(*, null) = *
- * StringUtils.removeStartIgnoreCase("www.domain.com", "www.") = "domain.com"
- * StringUtils.removeStartIgnoreCase("www.domain.com", "WWW.") = "domain.com"
- * StringUtils.removeStartIgnoreCase("domain.com", "www.") = "domain.com"
- * StringUtils.removeStartIgnoreCase("www.domain.com", "domain") = "www.domain.com"
- * StringUtils.removeStartIgnoreCase("abc", "") = "abc"
- *
- *
- * @param str the source String to search, may be null
- * @param remove the String to search for (case insensitive) and remove, may be null
- * @return the substring with the string removed if found,
- * {@code null} if null String input
- * @since 2.4
- */
- public static String removeStartIgnoreCase(String str, String remove) {
- if (isEmpty(str) || isEmpty(remove)) {
- return str;
- }
- if (startsWithIgnoreCase(str, remove)) {
- return str.substring(remove.length());
- }
- return str;
- }
-
- /**
- * Removes a substring only if it is at the end of a source string,
- * otherwise returns the source string.
- *
- * A {@code null} source string will return {@code null}.
- * An empty ("") source string will return the empty string.
- * A {@code null} search string will return the source string.
- *
- *
- * StringUtils.removeEnd(null, *) = null
- * StringUtils.removeEnd("", *) = ""
- * StringUtils.removeEnd(*, null) = *
- * StringUtils.removeEnd("www.domain.com", ".com.") = "www.domain.com"
- * StringUtils.removeEnd("www.domain.com", ".com") = "www.domain"
- * StringUtils.removeEnd("www.domain.com", "domain") = "www.domain.com"
- * StringUtils.removeEnd("abc", "") = "abc"
- *
- *
- * @param str the source String to search, may be null
- * @param remove the String to search for and remove, may be null
- * @return the substring with the string removed if found,
- * {@code null} if null String input
- * @since 2.1
- */
- public static String removeEnd(String str, String remove) {
- if (isEmpty(str) || isEmpty(remove)) {
- return str;
- }
- if (str.endsWith(remove)) {
- return str.substring(0, str.length() - remove.length());
- }
- return str;
- }
-
- /**
- * Case insensitive removal of a substring if it is at the end of a source string,
- * otherwise returns the source string.
- *
- * A {@code null} source string will return {@code null}.
- * An empty ("") source string will return the empty string.
- * A {@code null} search string will return the source string.
- *
- *
- * StringUtils.removeEndIgnoreCase(null, *) = null
- * StringUtils.removeEndIgnoreCase("", *) = ""
- * StringUtils.removeEndIgnoreCase(*, null) = *
- * StringUtils.removeEndIgnoreCase("www.domain.com", ".com.") = "www.domain.com"
- * StringUtils.removeEndIgnoreCase("www.domain.com", ".com") = "www.domain"
- * StringUtils.removeEndIgnoreCase("www.domain.com", "domain") = "www.domain.com"
- * StringUtils.removeEndIgnoreCase("abc", "") = "abc"
- * StringUtils.removeEndIgnoreCase("www.domain.com", ".COM") = "www.domain")
- * StringUtils.removeEndIgnoreCase("www.domain.COM", ".com") = "www.domain")
- *
- *
- * @param str the source String to search, may be null
- * @param remove the String to search for (case insensitive) and remove, may be null
- * @return the substring with the string removed if found,
- * {@code null} if null String input
- * @since 2.4
- */
- public static String removeEndIgnoreCase(String str, String remove) {
- if (isEmpty(str) || isEmpty(remove)) {
- return str;
- }
- if (endsWithIgnoreCase(str, remove)) {
- return str.substring(0, str.length() - remove.length());
- }
- return str;
- }
-
- /**
- * Removes all occurrences of a substring from within the source string.
- *
- * A {@code null} source string will return {@code null}.
- * An empty ("") source string will return the empty string.
- * A {@code null} remove string will return the source string.
- * An empty ("") remove string will return the source string.
- *
- *
- * StringUtils.remove(null, *) = null
- * StringUtils.remove("", *) = ""
- * StringUtils.remove(*, null) = *
- * StringUtils.remove(*, "") = *
- * StringUtils.remove("queued", "ue") = "qd"
- * StringUtils.remove("queued", "zz") = "queued"
- *
- *
- * @param str the source String to search, may be null
- * @param remove the String to search for and remove, may be null
- * @return the substring with the string removed if found,
- * {@code null} if null String input
- * @since 2.1
- */
- public static String remove(String str, String remove) {
- if (isEmpty(str) || isEmpty(remove)) {
- return str;
- }
- return replace(str, remove, EMPTY, -1);
- }
-
- /**
- * Removes all occurrences of a character from within the source string.
- *
- * A {@code null} source string will return {@code null}.
- * An empty ("") source string will return the empty string.
- *
- *
- * StringUtils.remove(null, *) = null
- * StringUtils.remove("", *) = ""
- * StringUtils.remove("queued", 'u') = "qeed"
- * StringUtils.remove("queued", 'z') = "queued"
- *
- *
- * @param str the source String to search, may be null
- * @param remove the char to search for and remove, may be null
- * @return the substring with the char removed if found,
- * {@code null} if null String input
- * @since 2.1
- */
- public static String remove(String str, char remove) {
- if (isEmpty(str) || str.indexOf(remove) == INDEX_NOT_FOUND) {
- return str;
- }
- char[] chars = str.toCharArray();
- int pos = 0;
- for (int i = 0; i < chars.length; i++) {
- if (chars[i] != remove) {
- chars[pos++] = chars[i];
- }
- }
- return new String(chars, 0, pos);
- }
-
- // Replacing
- //-----------------------------------------------------------------------
- /**
- * Replaces a String with another String inside a larger String, once.
- *
- * A {@code null} reference passed to this method is a no-op.
- *
- *
- * StringUtils.replaceOnce(null, *, *) = null
- * StringUtils.replaceOnce("", *, *) = ""
- * StringUtils.replaceOnce("any", null, *) = "any"
- * StringUtils.replaceOnce("any", *, null) = "any"
- * StringUtils.replaceOnce("any", "", *) = "any"
- * StringUtils.replaceOnce("aba", "a", null) = "aba"
- * StringUtils.replaceOnce("aba", "a", "") = "ba"
- * StringUtils.replaceOnce("aba", "a", "z") = "zba"
- *
- *
- * @see #replace(String text, String searchString, String replacement, int max)
- * @param text text to search and replace in, may be null
- * @param searchString the String to search for, may be null
- * @param replacement the String to replace with, may be null
- * @return the text with any replacements processed,
- * {@code null} if null String input
- */
- public static String replaceOnce(String text, String searchString, String replacement) {
- return replace(text, searchString, replacement, 1);
- }
-
- /**
- * Replaces all occurrences of a String within another String.
- *
- * A {@code null} reference passed to this method is a no-op.
- *
- *
- * StringUtils.replace(null, *, *) = null
- * StringUtils.replace("", *, *) = ""
- * StringUtils.replace("any", null, *) = "any"
- * StringUtils.replace("any", *, null) = "any"
- * StringUtils.replace("any", "", *) = "any"
- * StringUtils.replace("aba", "a", null) = "aba"
- * StringUtils.replace("aba", "a", "") = "b"
- * StringUtils.replace("aba", "a", "z") = "zbz"
- *
- *
- * @see #replace(String text, String searchString, String replacement, int max)
- * @param text text to search and replace in, may be null
- * @param searchString the String to search for, may be null
- * @param replacement the String to replace it with, may be null
- * @return the text with any replacements processed,
- * {@code null} if null String input
- */
- public static String replace(String text, String searchString, String replacement) {
- return replace(text, searchString, replacement, -1);
- }
-
- /**
- * Replaces a String with another String inside a larger String,
- * for the first {@code max} values of the search String.
- *
- * A {@code null} reference passed to this method is a no-op.
- *
- *
- * StringUtils.replace(null, *, *, *) = null
- * StringUtils.replace("", *, *, *) = ""
- * StringUtils.replace("any", null, *, *) = "any"
- * StringUtils.replace("any", *, null, *) = "any"
- * StringUtils.replace("any", "", *, *) = "any"
- * StringUtils.replace("any", *, *, 0) = "any"
- * StringUtils.replace("abaa", "a", null, -1) = "abaa"
- * StringUtils.replace("abaa", "a", "", -1) = "b"
- * StringUtils.replace("abaa", "a", "z", 0) = "abaa"
- * StringUtils.replace("abaa", "a", "z", 1) = "zbaa"
- * StringUtils.replace("abaa", "a", "z", 2) = "zbza"
- * StringUtils.replace("abaa", "a", "z", -1) = "zbzz"
- *
- *
- * @param text text to search and replace in, may be null
- * @param searchString the String to search for, may be null
- * @param replacement the String to replace it with, may be null
- * @param max maximum number of values to replace, or {@code -1} if no maximum
- * @return the text with any replacements processed,
- * {@code null} if null String input
- */
- public static String replace(String text, String searchString, String replacement, int max) {
- if (isEmpty(text) || isEmpty(searchString) || replacement == null || max == 0) {
- return text;
- }
- int start = 0;
- int end = text.indexOf(searchString, start);
- if (end == INDEX_NOT_FOUND) {
- return text;
- }
- int replLength = searchString.length();
- int increase = replacement.length() - replLength;
- increase = increase < 0 ? 0 : increase;
- increase *= max < 0 ? 16 : max > 64 ? 64 : max;
- StringBuilder buf = new StringBuilder(text.length() + increase);
- while (end != INDEX_NOT_FOUND) {
- buf.append(text.substring(start, end)).append(replacement);
- start = end + replLength;
- if (--max == 0) {
- break;
- }
- end = text.indexOf(searchString, start);
- }
- buf.append(text.substring(start));
- return buf.toString();
- }
-
- /**
- *
- * Replaces all occurrences of Strings within another String.
- *
- *
- *
- * A {@code null} reference passed to this method is a no-op, or if
- * any "search string" or "string to replace" is null, that replace will be
- * ignored. This will not repeat. For repeating replaces, call the
- * overloaded method.
- *
- *
- *
- * StringUtils.replaceEach(null, *, *) = null
- * StringUtils.replaceEach("", *, *) = ""
- * StringUtils.replaceEach("aba", null, null) = "aba"
- * StringUtils.replaceEach("aba", new String[0], null) = "aba"
- * StringUtils.replaceEach("aba", null, new String[0]) = "aba"
- * StringUtils.replaceEach("aba", new String[]{"a"}, null) = "aba"
- * StringUtils.replaceEach("aba", new String[]{"a"}, new String[]{""}) = "b"
- * StringUtils.replaceEach("aba", new String[]{null}, new String[]{"a"}) = "aba"
- * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"w", "t"}) = "wcte"
- * (example of how it does not repeat)
- * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d", "t"}) = "dcte"
- *
- *
- * @param text
- * text to search and replace in, no-op if null
- * @param searchList
- * the Strings to search for, no-op if null
- * @param replacementList
- * the Strings to replace them with, no-op if null
- * @return the text with any replacements processed, {@code null} if
- * null String input
- * @throws IllegalArgumentException
- * if the lengths of the arrays are not the same (null is ok,
- * and/or size 0)
- * @since 2.4
- */
- public static String replaceEach(String text, String[] searchList, String[] replacementList) {
- return replaceEach(text, searchList, replacementList, false, 0);
- }
-
- /**
- *
- * Replaces all occurrences of Strings within another String.
- *
- *
- *
- * A {@code null} reference passed to this method is a no-op, or if
- * any "search string" or "string to replace" is null, that replace will be
- * ignored.
- *
- *
- *
- * StringUtils.replaceEach(null, *, *, *) = null
- * StringUtils.replaceEach("", *, *, *) = ""
- * StringUtils.replaceEach("aba", null, null, *) = "aba"
- * StringUtils.replaceEach("aba", new String[0], null, *) = "aba"
- * StringUtils.replaceEach("aba", null, new String[0], *) = "aba"
- * StringUtils.replaceEach("aba", new String[]{"a"}, null, *) = "aba"
- * StringUtils.replaceEach("aba", new String[]{"a"}, new String[]{""}, *) = "b"
- * StringUtils.replaceEach("aba", new String[]{null}, new String[]{"a"}, *) = "aba"
- * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"w", "t"}, *) = "wcte"
- * (example of how it repeats)
- * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d", "t"}, false) = "dcte"
- * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d", "t"}, true) = "tcte"
- * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d", "ab"}, true) = IllegalStateException
- * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d", "ab"}, false) = "dcabe"
- *
- *
- * @param text
- * text to search and replace in, no-op if null
- * @param searchList
- * the Strings to search for, no-op if null
- * @param replacementList
- * the Strings to replace them with, no-op if null
- * @return the text with any replacements processed, {@code null} if
- * null String input
- * @throws IllegalStateException
- * if the search is repeating and there is an endless loop due
- * to outputs of one being inputs to another
- * @throws IllegalArgumentException
- * if the lengths of the arrays are not the same (null is ok,
- * and/or size 0)
- * @since 2.4
- */
- public static String replaceEachRepeatedly(String text, String[] searchList, String[] replacementList) {
- // timeToLive should be 0 if not used or nothing to replace, else it's
- // the length of the replace array
- int timeToLive = searchList == null ? 0 : searchList.length;
- return replaceEach(text, searchList, replacementList, true, timeToLive);
- }
-
- /**
- *
- * Replaces all occurrences of Strings within another String.
- *
- *
- *
- * A {@code null} reference passed to this method is a no-op, or if
- * any "search string" or "string to replace" is null, that replace will be
- * ignored.
- *
- *
- *
- * StringUtils.replaceEach(null, *, *, *) = null
- * StringUtils.replaceEach("", *, *, *) = ""
- * StringUtils.replaceEach("aba", null, null, *) = "aba"
- * StringUtils.replaceEach("aba", new String[0], null, *) = "aba"
- * StringUtils.replaceEach("aba", null, new String[0], *) = "aba"
- * StringUtils.replaceEach("aba", new String[]{"a"}, null, *) = "aba"
- * StringUtils.replaceEach("aba", new String[]{"a"}, new String[]{""}, *) = "b"
- * StringUtils.replaceEach("aba", new String[]{null}, new String[]{"a"}, *) = "aba"
- * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"w", "t"}, *) = "wcte"
- * (example of how it repeats)
- * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d", "t"}, false) = "dcte"
- * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d", "t"}, true) = "tcte"
- * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d", "ab"}, *) = IllegalStateException
- *
- *
- * @param text
- * text to search and replace in, no-op if null
- * @param searchList
- * the Strings to search for, no-op if null
- * @param replacementList
- * the Strings to replace them with, no-op if null
- * @param repeat if true, then replace repeatedly
- * until there are no more possible replacements or timeToLive < 0
- * @param timeToLive
- * if less than 0 then there is a circular reference and endless
- * loop
- * @return the text with any replacements processed, {@code null} if
- * null String input
- * @throws IllegalStateException
- * if the search is repeating and there is an endless loop due
- * to outputs of one being inputs to another
- * @throws IllegalArgumentException
- * if the lengths of the arrays are not the same (null is ok,
- * and/or size 0)
- * @since 2.4
- */
- private static String replaceEach(
- String text, String[] searchList, String[] replacementList, boolean repeat, int timeToLive) {
-
- // mchyzer Performance note: This creates very few new objects (one major goal)
- // let me know if there are performance requests, we can create a harness to measure
-
- if (text == null || text.length() == 0 || searchList == null ||
- searchList.length == 0 || replacementList == null || replacementList.length == 0) {
- return text;
- }
-
- // if recursing, this shouldn't be less than 0
- if (timeToLive < 0) {
- throw new IllegalStateException("Aborting to protect against StackOverflowError - " +
- "output of one loop is the input of another");
- }
-
- int searchLength = searchList.length;
- int replacementLength = replacementList.length;
-
- // make sure lengths are ok, these need to be equal
- if (searchLength != replacementLength) {
- throw new IllegalArgumentException("Search and Replace array lengths don't match: "
- + searchLength
- + " vs "
- + replacementLength);
- }
-
- // keep track of which still have matches
- boolean[] noMoreMatchesForReplIndex = new boolean[searchLength];
-
- // index on index that the match was found
- int textIndex = -1;
- int replaceIndex = -1;
- int tempIndex = -1;
-
- // index of replace array that will replace the search string found
- // NOTE: logic duplicated below START
- for (int i = 0; i < searchLength; i++) {
- if (noMoreMatchesForReplIndex[i] || searchList[i] == null ||
- searchList[i].length() == 0 || replacementList[i] == null) {
- continue;
- }
- tempIndex = text.indexOf(searchList[i]);
-
- // see if we need to keep searching for this
- if (tempIndex == -1) {
- noMoreMatchesForReplIndex[i] = true;
- } else {
- if (textIndex == -1 || tempIndex < textIndex) {
- textIndex = tempIndex;
- replaceIndex = i;
- }
- }
- }
- // NOTE: logic mostly below END
-
- // no search strings found, we are done
- if (textIndex == -1) {
- return text;
- }
-
- int start = 0;
-
- // get a good guess on the size of the result buffer so it doesn't have to double if it goes over a bit
- int increase = 0;
-
- // count the replacement text elements that are larger than their corresponding text being replaced
- for (int i = 0; i < searchList.length; i++) {
- if (searchList[i] == null || replacementList[i] == null) {
- continue;
- }
- int greater = replacementList[i].length() - searchList[i].length();
- if (greater > 0) {
- increase += 3 * greater; // assume 3 matches
- }
- }
- // have upper-bound at 20% increase, then let Java take over
- increase = Math.min(increase, text.length() / 5);
-
- StringBuilder buf = new StringBuilder(text.length() + increase);
-
- while (textIndex != -1) {
-
- for (int i = start; i < textIndex; i++) {
- buf.append(text.charAt(i));
- }
- buf.append(replacementList[replaceIndex]);
-
- start = textIndex + searchList[replaceIndex].length();
-
- textIndex = -1;
- replaceIndex = -1;
- tempIndex = -1;
- // find the next earliest match
- // NOTE: logic mostly duplicated above START
- for (int i = 0; i < searchLength; i++) {
- if (noMoreMatchesForReplIndex[i] || searchList[i] == null ||
- searchList[i].length() == 0 || replacementList[i] == null) {
- continue;
- }
- tempIndex = text.indexOf(searchList[i], start);
-
- // see if we need to keep searching for this
- if (tempIndex == -1) {
- noMoreMatchesForReplIndex[i] = true;
- } else {
- if (textIndex == -1 || tempIndex < textIndex) {
- textIndex = tempIndex;
- replaceIndex = i;
- }
- }
- }
- // NOTE: logic duplicated above END
-
- }
- int textLength = text.length();
- for (int i = start; i < textLength; i++) {
- buf.append(text.charAt(i));
- }
- String result = buf.toString();
- if (!repeat) {
- return result;
- }
-
- return replaceEach(result, searchList, replacementList, repeat, timeToLive - 1);
- }
-
- // Replace, character based
- //-----------------------------------------------------------------------
- /**
- * Replaces all occurrences of a character in a String with another.
- * This is a null-safe version of {@link String#replace(char, char)}.
- *
- * A {@code null} string input returns {@code null}.
- * An empty ("") string input returns an empty string.
- *
- *
- * StringUtils.replaceChars(null, *, *) = null
- * StringUtils.replaceChars("", *, *) = ""
- * StringUtils.replaceChars("abcba", 'b', 'y') = "aycya"
- * StringUtils.replaceChars("abcba", 'z', 'y') = "abcba"
- *
- *
- * @param str String to replace characters in, may be null
- * @param searchChar the character to search for, may be null
- * @param replaceChar the character to replace, may be null
- * @return modified String, {@code null} if null string input
- * @since 2.0
- */
- public static String replaceChars(String str, char searchChar, char replaceChar) {
- if (str == null) {
- return null;
- }
- return str.replace(searchChar, replaceChar);
- }
-
- /**
- * Replaces multiple characters in a String in one go.
- * This method can also be used to delete characters.
- *
- * For example:
- * replaceChars("hello", "ho", "jy") = jelly.
- *
- * A {@code null} string input returns {@code null}.
- * An empty ("") string input returns an empty string.
- * A null or empty set of search characters returns the input string.
- *
- * The length of the search characters should normally equal the length
- * of the replace characters.
- * If the search characters is longer, then the extra search characters
- * are deleted.
- * If the search characters is shorter, then the extra replace characters
- * are ignored.
- *
- *
- * StringUtils.replaceChars(null, *, *) = null
- * StringUtils.replaceChars("", *, *) = ""
- * StringUtils.replaceChars("abc", null, *) = "abc"
- * StringUtils.replaceChars("abc", "", *) = "abc"
- * StringUtils.replaceChars("abc", "b", null) = "ac"
- * StringUtils.replaceChars("abc", "b", "") = "ac"
- * StringUtils.replaceChars("abcba", "bc", "yz") = "ayzya"
- * StringUtils.replaceChars("abcba", "bc", "y") = "ayya"
- * StringUtils.replaceChars("abcba", "bc", "yzx") = "ayzya"
- *
- *
- * @param str String to replace characters in, may be null
- * @param searchChars a set of characters to search for, may be null
- * @param replaceChars a set of characters to replace, may be null
- * @return modified String, {@code null} if null string input
- * @since 2.0
- */
- public static String replaceChars(String str, String searchChars, String replaceChars) {
- if (isEmpty(str) || isEmpty(searchChars)) {
- return str;
- }
- if (replaceChars == null) {
- replaceChars = EMPTY;
- }
- boolean modified = false;
- int replaceCharsLength = replaceChars.length();
- int strLength = str.length();
- StringBuilder buf = new StringBuilder(strLength);
- for (int i = 0; i < strLength; i++) {
- char ch = str.charAt(i);
- int index = searchChars.indexOf(ch);
- if (index >= 0) {
- modified = true;
- if (index < replaceCharsLength) {
- buf.append(replaceChars.charAt(index));
- }
- } else {
- buf.append(ch);
- }
- }
- if (modified) {
- return buf.toString();
- }
- return str;
- }
-
- // Overlay
- //-----------------------------------------------------------------------
- /**
- * Overlays part of a String with another String.
- *
- * A {@code null} string input returns {@code null}.
- * A negative index is treated as zero.
- * An index greater than the string length is treated as the string length.
- * The start index is always the smaller of the two indices.
- *
- *
- * StringUtils.overlay(null, *, *, *) = null
- * StringUtils.overlay("", "abc", 0, 0) = "abc"
- * StringUtils.overlay("abcdef", null, 2, 4) = "abef"
- * StringUtils.overlay("abcdef", "", 2, 4) = "abef"
- * StringUtils.overlay("abcdef", "", 4, 2) = "abef"
- * StringUtils.overlay("abcdef", "zzzz", 2, 4) = "abzzzzef"
- * StringUtils.overlay("abcdef", "zzzz", 4, 2) = "abzzzzef"
- * StringUtils.overlay("abcdef", "zzzz", -1, 4) = "zzzzef"
- * StringUtils.overlay("abcdef", "zzzz", 2, 8) = "abzzzz"
- * StringUtils.overlay("abcdef", "zzzz", -2, -3) = "zzzzabcdef"
- * StringUtils.overlay("abcdef", "zzzz", 8, 10) = "abcdefzzzz"
- *
- *
- * @param str the String to do overlaying in, may be null
- * @param overlay the String to overlay, may be null
- * @param start the position to start overlaying at
- * @param end the position to stop overlaying before
- * @return overlayed String, {@code null} if null String input
- * @since 2.0
- */
- public static String overlay(String str, String overlay, int start, int end) {
- if (str == null) {
- return null;
- }
- if (overlay == null) {
- overlay = EMPTY;
- }
- int len = str.length();
- if (start < 0) {
- start = 0;
- }
- if (start > len) {
- start = len;
- }
- if (end < 0) {
- end = 0;
- }
- if (end > len) {
- end = len;
- }
- if (start > end) {
- int temp = start;
- start = end;
- end = temp;
- }
- return new StringBuilder(len + start - end + overlay.length() + 1)
- .append(str.substring(0, start))
- .append(overlay)
- .append(str.substring(end))
- .toString();
- }
-
- // Chomping
- //-----------------------------------------------------------------------
- /**
- * Removes one newline from end of a String if it's there,
- * otherwise leave it alone. A newline is "{@code \n}",
- * "{@code \r}", or "{@code \r\n}".
- *
- * NOTE: This method changed in 2.0.
- * It now more closely matches Perl chomp.
- *
- *
- * StringUtils.chomp(null) = null
- * StringUtils.chomp("") = ""
- * StringUtils.chomp("abc \r") = "abc "
- * StringUtils.chomp("abc\n") = "abc"
- * StringUtils.chomp("abc\r\n") = "abc"
- * StringUtils.chomp("abc\r\n\r\n") = "abc\r\n"
- * StringUtils.chomp("abc\n\r") = "abc\n"
- * StringUtils.chomp("abc\n\rabc") = "abc\n\rabc"
- * StringUtils.chomp("\r") = ""
- * StringUtils.chomp("\n") = ""
- * StringUtils.chomp("\r\n") = ""
- *
- *
- * @param str the String to chomp a newline from, may be null
- * @return String without newline, {@code null} if null String input
- */
- public static String chomp(String str) {
- if (isEmpty(str)) {
- return str;
- }
-
- if (str.length() == 1) {
- char ch = str.charAt(0);
- if (ch == CharUtils.CR || ch == CharUtils.LF) {
- return EMPTY;
- }
- return str;
- }
-
- int lastIdx = str.length() - 1;
- char last = str.charAt(lastIdx);
-
- if (last == CharUtils.LF) {
- if (str.charAt(lastIdx - 1) == CharUtils.CR) {
- lastIdx--;
- }
- } else if (last != CharUtils.CR) {
- lastIdx++;
- }
- return str.substring(0, lastIdx);
- }
-
- /**
- * Removes {@code separator} from the end of
- * {@code str} if it's there, otherwise leave it alone.
- *
- * NOTE: This method changed in version 2.0.
- * It now more closely matches Perl chomp.
- * For the previous behavior, use {@link #substringBeforeLast(String, String)}.
- * This method uses {@link String#endsWith(String)}.
- *
- *
- * StringUtils.chomp(null, *) = null
- * StringUtils.chomp("", *) = ""
- * StringUtils.chomp("foobar", "bar") = "foo"
- * StringUtils.chomp("foobar", "baz") = "foobar"
- * StringUtils.chomp("foo", "foo") = ""
- * StringUtils.chomp("foo ", "foo") = "foo "
- * StringUtils.chomp(" foo", "foo") = " "
- * StringUtils.chomp("foo", "foooo") = "foo"
- * StringUtils.chomp("foo", "") = "foo"
- * StringUtils.chomp("foo", null) = "foo"
- *
- *
- * @param str the String to chomp from, may be null
- * @param separator separator String, may be null
- * @return String without trailing separator, {@code null} if null String input
- * @deprecated This feature will be removed in Lang 4.0, use {@link StringUtils#removeEnd(String, String)} instead
- */
- @Deprecated
- public static String chomp(String str, String separator) {
- return removeEnd(str,separator);
- }
-
- // Chopping
- //-----------------------------------------------------------------------
- /**
- * Remove the last character from a String.
- *
- * If the String ends in {@code \r\n}, then remove both
- * of them.
- *
- *
- * StringUtils.chop(null) = null
- * StringUtils.chop("") = ""
- * StringUtils.chop("abc \r") = "abc "
- * StringUtils.chop("abc\n") = "abc"
- * StringUtils.chop("abc\r\n") = "abc"
- * StringUtils.chop("abc") = "ab"
- * StringUtils.chop("abc\nabc") = "abc\nab"
- * StringUtils.chop("a") = ""
- * StringUtils.chop("\r") = ""
- * StringUtils.chop("\n") = ""
- * StringUtils.chop("\r\n") = ""
- *
- *
- * @param str the String to chop last character from, may be null
- * @return String without last character, {@code null} if null String input
- */
- public static String chop(String str) {
- if (str == null) {
- return null;
- }
- int strLen = str.length();
- if (strLen < 2) {
- return EMPTY;
- }
- int lastIdx = strLen - 1;
- String ret = str.substring(0, lastIdx);
- char last = str.charAt(lastIdx);
- if (last == CharUtils.LF && ret.charAt(lastIdx - 1) == CharUtils.CR) {
- return ret.substring(0, lastIdx - 1);
- }
- return ret;
- }
-
- // Conversion
- //-----------------------------------------------------------------------
-
- // Padding
- //-----------------------------------------------------------------------
- /**
- * Repeat a String {@code repeat} times to form a
- * new String.
- *
- *
- * StringUtils.repeat(null, 2) = null
- * StringUtils.repeat("", 0) = ""
- * StringUtils.repeat("", 2) = ""
- * StringUtils.repeat("a", 3) = "aaa"
- * StringUtils.repeat("ab", 2) = "abab"
- * StringUtils.repeat("a", -2) = ""
- *
- *
- * @param str the String to repeat, may be null
- * @param repeat number of times to repeat str, negative treated as zero
- * @return a new String consisting of the original String repeated,
- * {@code null} if null String input
- */
- public static String repeat(String str, int repeat) {
- // Performance tuned for 2.0 (JDK1.4)
-
- if (str == null) {
- return null;
- }
- if (repeat <= 0) {
- return EMPTY;
- }
- int inputLength = str.length();
- if (repeat == 1 || inputLength == 0) {
- return str;
- }
- if (inputLength == 1 && repeat <= PAD_LIMIT) {
- return repeat(str.charAt(0), repeat);
- }
-
- int outputLength = inputLength * repeat;
- switch (inputLength) {
- case 1 :
- return repeat(str.charAt(0), repeat);
- case 2 :
- char ch0 = str.charAt(0);
- char ch1 = str.charAt(1);
- char[] output2 = new char[outputLength];
- for (int i = repeat * 2 - 2; i >= 0; i--, i--) {
- output2[i] = ch0;
- output2[i + 1] = ch1;
- }
- return new String(output2);
- default :
- StringBuilder buf = new StringBuilder(outputLength);
- for (int i = 0; i < repeat; i++) {
- buf.append(str);
- }
- return buf.toString();
- }
- }
-
- /**
- * Repeat a String {@code repeat} times to form a
- * new String, with a String separator injected each time.
- *
- *
- * StringUtils.repeat(null, null, 2) = null
- * StringUtils.repeat(null, "x", 2) = null
- * StringUtils.repeat("", null, 0) = ""
- * StringUtils.repeat("", "", 2) = ""
- * StringUtils.repeat("", "x", 3) = "xxx"
- * StringUtils.repeat("?", ", ", 3) = "?, ?, ?"
- *
- *
- * @param str the String to repeat, may be null
- * @param separator the String to inject, may be null
- * @param repeat number of times to repeat str, negative treated as zero
- * @return a new String consisting of the original String repeated,
- * {@code null} if null String input
- * @since 2.5
- */
- public static String repeat(String str, String separator, int repeat) {
- if(str == null || separator == null) {
- return repeat(str, repeat);
- } else {
- // given that repeat(String, int) is quite optimized, better to rely on it than try and splice this into it
- String result = repeat(str + separator, repeat);
- return removeEnd(result, separator);
- }
- }
-
- /**
- * Returns padding using the specified delimiter repeated
- * to a given length.
- *
- *
- * StringUtils.repeat(0, 'e') = ""
- * StringUtils.repeat(3, 'e') = "eee"
- * StringUtils.repeat(-2, 'e') = ""
- *
- *
- * Note: this method doesn't not support padding with
- * Unicode Supplementary Characters
- * as they require a pair of {@code char}s to be represented.
- * If you are needing to support full I18N of your applications
- * consider using {@link #repeat(String, int)} instead.
- *
- *
- * @param ch character to repeat
- * @param repeat number of times to repeat char, negative treated as zero
- * @return String with repeated character
- * @see #repeat(String, int)
- */
- public static String repeat(char ch, int repeat) {
- char[] buf = new char[repeat];
- for (int i = repeat - 1; i >= 0; i--) {
- buf[i] = ch;
- }
- return new String(buf);
- }
-
- /**
- * Right pad a String with spaces (' ').
- *
- * The String is padded to the size of {@code size}.
- *
- *
- * StringUtils.rightPad(null, *) = null
- * StringUtils.rightPad("", 3) = " "
- * StringUtils.rightPad("bat", 3) = "bat"
- * StringUtils.rightPad("bat", 5) = "bat "
- * StringUtils.rightPad("bat", 1) = "bat"
- * StringUtils.rightPad("bat", -1) = "bat"
- *
- *
- * @param str the String to pad out, may be null
- * @param size the size to pad to
- * @return right padded String or original String if no padding is necessary,
- * {@code null} if null String input
- */
- public static String rightPad(String str, int size) {
- return rightPad(str, size, ' ');
- }
-
- /**
- * Right pad a String with a specified character.
- *
- * The String is padded to the size of {@code size}.
- *
- *
- * StringUtils.rightPad(null, *, *) = null
- * StringUtils.rightPad("", 3, 'z') = "zzz"
- * StringUtils.rightPad("bat", 3, 'z') = "bat"
- * StringUtils.rightPad("bat", 5, 'z') = "batzz"
- * StringUtils.rightPad("bat", 1, 'z') = "bat"
- * StringUtils.rightPad("bat", -1, 'z') = "bat"
- *
- *
- * @param str the String to pad out, may be null
- * @param size the size to pad to
- * @param padChar the character to pad with
- * @return right padded String or original String if no padding is necessary,
- * {@code null} if null String input
- * @since 2.0
- */
- public static String rightPad(String str, int size, char padChar) {
- if (str == null) {
- return null;
- }
- int pads = size - str.length();
- if (pads <= 0) {
- return str; // returns original String when possible
- }
- if (pads > PAD_LIMIT) {
- return rightPad(str, size, String.valueOf(padChar));
- }
- return str.concat(repeat(padChar, pads));
- }
-
- /**
- * Right pad a String with a specified String.
- *
- * The String is padded to the size of {@code size}.
- *
- *
- * StringUtils.rightPad(null, *, *) = null
- * StringUtils.rightPad("", 3, "z") = "zzz"
- * StringUtils.rightPad("bat", 3, "yz") = "bat"
- * StringUtils.rightPad("bat", 5, "yz") = "batyz"
- * StringUtils.rightPad("bat", 8, "yz") = "batyzyzy"
- * StringUtils.rightPad("bat", 1, "yz") = "bat"
- * StringUtils.rightPad("bat", -1, "yz") = "bat"
- * StringUtils.rightPad("bat", 5, null) = "bat "
- * StringUtils.rightPad("bat", 5, "") = "bat "
- *
- *
- * @param str the String to pad out, may be null
- * @param size the size to pad to
- * @param padStr the String to pad with, null or empty treated as single space
- * @return right padded String or original String if no padding is necessary,
- * {@code null} if null String input
- */
- public static String rightPad(String str, int size, String padStr) {
- if (str == null) {
- return null;
- }
- if (isEmpty(padStr)) {
- padStr = " ";
- }
- int padLen = padStr.length();
- int strLen = str.length();
- int pads = size - strLen;
- if (pads <= 0) {
- return str; // returns original String when possible
- }
- if (padLen == 1 && pads <= PAD_LIMIT) {
- return rightPad(str, size, padStr.charAt(0));
- }
-
- if (pads == padLen) {
- return str.concat(padStr);
- } else if (pads < padLen) {
- return str.concat(padStr.substring(0, pads));
- } else {
- char[] padding = new char[pads];
- char[] padChars = padStr.toCharArray();
- for (int i = 0; i < pads; i++) {
- padding[i] = padChars[i % padLen];
- }
- return str.concat(new String(padding));
- }
- }
-
- /**
- * Left pad a String with spaces (' ').
- *
- * The String is padded to the size of {@code size}.
- *
- *
- * StringUtils.leftPad(null, *) = null
- * StringUtils.leftPad("", 3) = " "
- * StringUtils.leftPad("bat", 3) = "bat"
- * StringUtils.leftPad("bat", 5) = " bat"
- * StringUtils.leftPad("bat", 1) = "bat"
- * StringUtils.leftPad("bat", -1) = "bat"
- *
- *
- * @param str the String to pad out, may be null
- * @param size the size to pad to
- * @return left padded String or original String if no padding is necessary,
- * {@code null} if null String input
- */
- public static String leftPad(String str, int size) {
- return leftPad(str, size, ' ');
- }
-
- /**
- * Left pad a String with a specified character.
- *
- * Pad to a size of {@code size}.
- *
- *
- * StringUtils.leftPad(null, *, *) = null
- * StringUtils.leftPad("", 3, 'z') = "zzz"
- * StringUtils.leftPad("bat", 3, 'z') = "bat"
- * StringUtils.leftPad("bat", 5, 'z') = "zzbat"
- * StringUtils.leftPad("bat", 1, 'z') = "bat"
- * StringUtils.leftPad("bat", -1, 'z') = "bat"
- *
- *
- * @param str the String to pad out, may be null
- * @param size the size to pad to
- * @param padChar the character to pad with
- * @return left padded String or original String if no padding is necessary,
- * {@code null} if null String input
- * @since 2.0
- */
- public static String leftPad(String str, int size, char padChar) {
- if (str == null) {
- return null;
- }
- int pads = size - str.length();
- if (pads <= 0) {
- return str; // returns original String when possible
- }
- if (pads > PAD_LIMIT) {
- return leftPad(str, size, String.valueOf(padChar));
- }
- return repeat(padChar, pads).concat(str);
- }
-
- /**
- * Left pad a String with a specified String.
- *
- * Pad to a size of {@code size}.
- *
- *
- * StringUtils.leftPad(null, *, *) = null
- * StringUtils.leftPad("", 3, "z") = "zzz"
- * StringUtils.leftPad("bat", 3, "yz") = "bat"
- * StringUtils.leftPad("bat", 5, "yz") = "yzbat"
- * StringUtils.leftPad("bat", 8, "yz") = "yzyzybat"
- * StringUtils.leftPad("bat", 1, "yz") = "bat"
- * StringUtils.leftPad("bat", -1, "yz") = "bat"
- * StringUtils.leftPad("bat", 5, null) = " bat"
- * StringUtils.leftPad("bat", 5, "") = " bat"
- *
- *
- * @param str the String to pad out, may be null
- * @param size the size to pad to
- * @param padStr the String to pad with, null or empty treated as single space
- * @return left padded String or original String if no padding is necessary,
- * {@code null} if null String input
- */
- public static String leftPad(String str, int size, String padStr) {
- if (str == null) {
- return null;
- }
- if (isEmpty(padStr)) {
- padStr = " ";
- }
- int padLen = padStr.length();
- int strLen = str.length();
- int pads = size - strLen;
- if (pads <= 0) {
- return str; // returns original String when possible
- }
- if (padLen == 1 && pads <= PAD_LIMIT) {
- return leftPad(str, size, padStr.charAt(0));
- }
-
- if (pads == padLen) {
- return padStr.concat(str);
- } else if (pads < padLen) {
- return padStr.substring(0, pads).concat(str);
- } else {
- char[] padding = new char[pads];
- char[] padChars = padStr.toCharArray();
- for (int i = 0; i < pads; i++) {
- padding[i] = padChars[i % padLen];
- }
- return new String(padding).concat(str);
- }
- }
-
- /**
- * Gets a CharSequence length or {@code 0} if the CharSequence is
- * {@code null}.
- *
- * @param cs
- * a CharSequence or {@code null}
- * @return CharSequence length or {@code 0} if the CharSequence is
- * {@code null}.
- * @since 2.4
- * @since 3.0 Changed signature from length(String) to length(CharSequence)
- */
- public static int length(CharSequence cs) {
- return cs == null ? 0 : cs.length();
- }
-
- // Centering
- //-----------------------------------------------------------------------
- /**
- * Centers a String in a larger String of size {@code size}
- * using the space character (' ').
- *
- *
If the size is less than the String length, the String is returned.
- * A {@code null} String returns {@code null}.
- * A negative size is treated as zero.
- *
- * Equivalent to {@code center(str, size, " ")}.
- *
- *
- * StringUtils.center(null, *) = null
- * StringUtils.center("", 4) = " "
- * StringUtils.center("ab", -1) = "ab"
- * StringUtils.center("ab", 4) = " ab "
- * StringUtils.center("abcd", 2) = "abcd"
- * StringUtils.center("a", 4) = " a "
- *
- *
- * @param str the String to center, may be null
- * @param size the int size of new String, negative treated as zero
- * @return centered String, {@code null} if null String input
- */
- public static String center(String str, int size) {
- return center(str, size, ' ');
- }
-
- /**
- * Centers a String in a larger String of size {@code size}.
- * Uses a supplied character as the value to pad the String with.
- *
- * If the size is less than the String length, the String is returned.
- * A {@code null} String returns {@code null}.
- * A negative size is treated as zero.
- *
- *
- * StringUtils.center(null, *, *) = null
- * StringUtils.center("", 4, ' ') = " "
- * StringUtils.center("ab", -1, ' ') = "ab"
- * StringUtils.center("ab", 4, ' ') = " ab"
- * StringUtils.center("abcd", 2, ' ') = "abcd"
- * StringUtils.center("a", 4, ' ') = " a "
- * StringUtils.center("a", 4, 'y') = "yayy"
- *
- *
- * @param str the String to center, may be null
- * @param size the int size of new String, negative treated as zero
- * @param padChar the character to pad the new String with
- * @return centered String, {@code null} if null String input
- * @since 2.0
- */
- public static String center(String str, int size, char padChar) {
- if (str == null || size <= 0) {
- return str;
- }
- int strLen = str.length();
- int pads = size - strLen;
- if (pads <= 0) {
- return str;
- }
- str = leftPad(str, strLen + pads / 2, padChar);
- str = rightPad(str, size, padChar);
- return str;
- }
-
- /**
- * Centers a String in a larger String of size {@code size}.
- * Uses a supplied String as the value to pad the String with.
- *
- * If the size is less than the String length, the String is returned.
- * A {@code null} String returns {@code null}.
- * A negative size is treated as zero.
- *
- *
- * StringUtils.center(null, *, *) = null
- * StringUtils.center("", 4, " ") = " "
- * StringUtils.center("ab", -1, " ") = "ab"
- * StringUtils.center("ab", 4, " ") = " ab"
- * StringUtils.center("abcd", 2, " ") = "abcd"
- * StringUtils.center("a", 4, " ") = " a "
- * StringUtils.center("a", 4, "yz") = "yayz"
- * StringUtils.center("abc", 7, null) = " abc "
- * StringUtils.center("abc", 7, "") = " abc "
- *
- *
- * @param str the String to center, may be null
- * @param size the int size of new String, negative treated as zero
- * @param padStr the String to pad the new String with, must not be null or empty
- * @return centered String, {@code null} if null String input
- * @throws IllegalArgumentException if padStr is {@code null} or empty
- */
- public static String center(String str, int size, String padStr) {
- if (str == null || size <= 0) {
- return str;
- }
- if (isEmpty(padStr)) {
- padStr = " ";
- }
- int strLen = str.length();
- int pads = size - strLen;
- if (pads <= 0) {
- return str;
- }
- str = leftPad(str, strLen + pads / 2, padStr);
- str = rightPad(str, size, padStr);
- return str;
- }
-
- // Case conversion
- //-----------------------------------------------------------------------
- /**
- * Converts a String to upper case as per {@link String#toUpperCase()}.
- *
- * A {@code null} input String returns {@code null}.
- *
- *
- * StringUtils.upperCase(null) = null
- * StringUtils.upperCase("") = ""
- * StringUtils.upperCase("aBc") = "ABC"
- *
- *
- * Note: As described in the documentation for {@link String#toUpperCase()},
- * the result of this method is affected by the current locale.
- * For platform-independent case transformations, the method {@link #lowerCase(String, Locale)}
- * should be used with a specific locale (e.g. {@link Locale#ENGLISH}).
- *
- * @param str the String to upper case, may be null
- * @return the upper cased String, {@code null} if null String input
- */
- public static String upperCase(String str) {
- if (str == null) {
- return null;
- }
- return str.toUpperCase();
- }
-
- /**
- * Converts a String to upper case as per {@link String#toUpperCase(Locale)}.
- *
- * A {@code null} input String returns {@code null}.
- *
- *
- * StringUtils.upperCase(null, Locale.ENGLISH) = null
- * StringUtils.upperCase("", Locale.ENGLISH) = ""
- * StringUtils.upperCase("aBc", Locale.ENGLISH) = "ABC"
- *
- *
- * @param str the String to upper case, may be null
- * @param locale the locale that defines the case transformation rules, must not be null
- * @return the upper cased String, {@code null} if null String input
- * @since 2.5
- */
- public static String upperCase(String str, Locale locale) {
- if (str == null) {
- return null;
- }
- return str.toUpperCase(locale);
- }
-
- /**
- * Converts a String to lower case as per {@link String#toLowerCase()}.
- *
- * A {@code null} input String returns {@code null}.
- *
- *
- * StringUtils.lowerCase(null) = null
- * StringUtils.lowerCase("") = ""
- * StringUtils.lowerCase("aBc") = "abc"
- *
- *
- * Note: As described in the documentation for {@link String#toLowerCase()},
- * the result of this method is affected by the current locale.
- * For platform-independent case transformations, the method {@link #lowerCase(String, Locale)}
- * should be used with a specific locale (e.g. {@link Locale#ENGLISH}).
- *
- * @param str the String to lower case, may be null
- * @return the lower cased String, {@code null} if null String input
- */
- public static String lowerCase(String str) {
- if (str == null) {
- return null;
- }
- return str.toLowerCase();
- }
-
- /**
- * Converts a String to lower case as per {@link String#toLowerCase(Locale)}.
- *
- * A {@code null} input String returns {@code null}.
- *
- *
- * StringUtils.lowerCase(null, Locale.ENGLISH) = null
- * StringUtils.lowerCase("", Locale.ENGLISH) = ""
- * StringUtils.lowerCase("aBc", Locale.ENGLISH) = "abc"
- *
- *
- * @param str the String to lower case, may be null
- * @param locale the locale that defines the case transformation rules, must not be null
- * @return the lower cased String, {@code null} if null String input
- * @since 2.5
- */
- public static String lowerCase(String str, Locale locale) {
- if (str == null) {
- return null;
- }
- return str.toLowerCase(locale);
- }
-
- /**
- * Capitalizes a String changing the first letter to title case as
- * per {@link Character#toTitleCase(char)}. No other letters are changed.
- *
- * For a word based algorithm, see {@link external.org.apache.commons.lang3.text.WordUtils#capitalize(String)}.
- * A {@code null} input String returns {@code null}.
- *
- *
- * StringUtils.capitalize(null) = null
- * StringUtils.capitalize("") = ""
- * StringUtils.capitalize("cat") = "Cat"
- * StringUtils.capitalize("cAt") = "CAt"
- *
- *
- * @param str the String to capitalize, may be null
- * @return the capitalized String, {@code null} if null String input
- * @see external.org.apache.commons.lang3.text.WordUtils#capitalize(String)
- * @see #uncapitalize(String)
- * @since 2.0
- */
- public static String capitalize(String str) {
- int strLen;
- if (str == null || (strLen = str.length()) == 0) {
- return str;
- }
- return new StringBuilder(strLen)
- .append(Character.toTitleCase(str.charAt(0)))
- .append(str.substring(1))
- .toString();
- }
-
- /**
- * Uncapitalizes a String changing the first letter to title case as
- * per {@link Character#toLowerCase(char)}. No other letters are changed.
- *
- * For a word based algorithm, see {@link external.org.apache.commons.lang3.text.WordUtils#uncapitalize(String)}.
- * A {@code null} input String returns {@code null}.
- *
- *
- * StringUtils.uncapitalize(null) = null
- * StringUtils.uncapitalize("") = ""
- * StringUtils.uncapitalize("Cat") = "cat"
- * StringUtils.uncapitalize("CAT") = "cAT"
- *
- *
- * @param str the String to uncapitalize, may be null
- * @return the uncapitalized String, {@code null} if null String input
- * @see external.org.apache.commons.lang3.text.WordUtils#uncapitalize(String)
- * @see #capitalize(String)
- * @since 2.0
- */
- public static String uncapitalize(String str) {
- int strLen;
- if (str == null || (strLen = str.length()) == 0) {
- return str;
- }
- return new StringBuilder(strLen)
- .append(Character.toLowerCase(str.charAt(0)))
- .append(str.substring(1))
- .toString();
- }
-
- /**
- * Swaps the case of a String changing upper and title case to
- * lower case, and lower case to upper case.
- *
- *
- * Upper case character converts to Lower case
- * Title case character converts to Lower case
- * Lower case character converts to Upper case
- *
- *
- * For a word based algorithm, see {@link external.org.apache.commons.lang3.text.WordUtils#swapCase(String)}.
- * A {@code null} input String returns {@code null}.
- *
- *
- * StringUtils.swapCase(null) = null
- * StringUtils.swapCase("") = ""
- * StringUtils.swapCase("The dog has a BONE") = "tHE DOG HAS A bone"
- *
- *
- * NOTE: This method changed in Lang version 2.0.
- * It no longer performs a word based algorithm.
- * If you only use ASCII, you will notice no change.
- * That functionality is available in org.apache.commons.lang3.text.WordUtils.
- *
- * @param str the String to swap case, may be null
- * @return the changed String, {@code null} if null String input
- */
- public static String swapCase(String str) {
- if (StringUtils.isEmpty(str)) {
- return str;
- }
-
- char[] buffer = str.toCharArray();
-
- for (int i = 0; i < buffer.length; i++) {
- char ch = buffer[i];
- if (Character.isUpperCase(ch)) {
- buffer[i] = Character.toLowerCase(ch);
- } else if (Character.isTitleCase(ch)) {
- buffer[i] = Character.toLowerCase(ch);
- } else if (Character.isLowerCase(ch)) {
- buffer[i] = Character.toUpperCase(ch);
- }
- }
- return new String(buffer);
- }
-
- // Count matches
- //-----------------------------------------------------------------------
- /**
- * Counts how many times the substring appears in the larger string.
- *
- * A {@code null} or empty ("") String input returns {@code 0}.
- *
- *
- * StringUtils.countMatches(null, *) = 0
- * StringUtils.countMatches("", *) = 0
- * StringUtils.countMatches("abba", null) = 0
- * StringUtils.countMatches("abba", "") = 0
- * StringUtils.countMatches("abba", "a") = 2
- * StringUtils.countMatches("abba", "ab") = 1
- * StringUtils.countMatches("abba", "xxx") = 0
- *
- *
- * @param str the CharSequence to check, may be null
- * @param sub the substring to count, may be null
- * @return the number of occurrences, 0 if either CharSequence is {@code null}
- * @since 3.0 Changed signature from countMatches(String, String) to countMatches(CharSequence, CharSequence)
- */
- public static int countMatches(CharSequence str, CharSequence sub) {
- if (isEmpty(str) || isEmpty(sub)) {
- return 0;
- }
- int count = 0;
- int idx = 0;
- while ((idx = CharSequenceUtils.indexOf(str, sub, idx)) != INDEX_NOT_FOUND) {
- count++;
- idx += sub.length();
- }
- return count;
- }
-
- // Character Tests
- //-----------------------------------------------------------------------
- /**
- * Checks if the CharSequence contains only Unicode letters.
- *
- * {@code null} will return {@code false}.
- * An empty CharSequence (length()=0) will return {@code false}.
- *
- *
- * StringUtils.isAlpha(null) = false
- * StringUtils.isAlpha("") = false
- * StringUtils.isAlpha(" ") = false
- * StringUtils.isAlpha("abc") = true
- * StringUtils.isAlpha("ab2c") = false
- * StringUtils.isAlpha("ab-c") = false
- *
- *
- * @param cs the CharSequence to check, may be null
- * @return {@code true} if only contains letters, and is non-null
- * @since 3.0 Changed signature from isAlpha(String) to isAlpha(CharSequence)
- * @since 3.0 Changed "" to return false and not true
- */
- public static boolean isAlpha(CharSequence cs) {
- if (cs == null || cs.length() == 0) {
- return false;
- }
- int sz = cs.length();
- for (int i = 0; i < sz; i++) {
- if (Character.isLetter(cs.charAt(i)) == false) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Checks if the CharSequence contains only Unicode letters and
- * space (' ').
- *
- * {@code null} will return {@code false}
- * An empty CharSequence (length()=0) will return {@code true}.
- *
- *
- * StringUtils.isAlphaSpace(null) = false
- * StringUtils.isAlphaSpace("") = true
- * StringUtils.isAlphaSpace(" ") = true
- * StringUtils.isAlphaSpace("abc") = true
- * StringUtils.isAlphaSpace("ab c") = true
- * StringUtils.isAlphaSpace("ab2c") = false
- * StringUtils.isAlphaSpace("ab-c") = false
- *
- *
- * @param cs the CharSequence to check, may be null
- * @return {@code true} if only contains letters and space,
- * and is non-null
- * @since 3.0 Changed signature from isAlphaSpace(String) to isAlphaSpace(CharSequence)
- */
- public static boolean isAlphaSpace(CharSequence cs) {
- if (cs == null) {
- return false;
- }
- int sz = cs.length();
- for (int i = 0; i < sz; i++) {
- if (Character.isLetter(cs.charAt(i)) == false && cs.charAt(i) != ' ') {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Checks if the CharSequence contains only Unicode letters or digits.
- *
- * {@code null} will return {@code false}.
- * An empty CharSequence (length()=0) will return {@code false}.
- *
- *
- * StringUtils.isAlphanumeric(null) = false
- * StringUtils.isAlphanumeric("") = false
- * StringUtils.isAlphanumeric(" ") = false
- * StringUtils.isAlphanumeric("abc") = true
- * StringUtils.isAlphanumeric("ab c") = false
- * StringUtils.isAlphanumeric("ab2c") = true
- * StringUtils.isAlphanumeric("ab-c") = false
- *
- *
- * @param cs the CharSequence to check, may be null
- * @return {@code true} if only contains letters or digits,
- * and is non-null
- * @since 3.0 Changed signature from isAlphanumeric(String) to isAlphanumeric(CharSequence)
- * @since 3.0 Changed "" to return false and not true
- */
- public static boolean isAlphanumeric(CharSequence cs) {
- if (cs == null || cs.length() == 0) {
- return false;
- }
- int sz = cs.length();
- for (int i = 0; i < sz; i++) {
- if (Character.isLetterOrDigit(cs.charAt(i)) == false) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Checks if the CharSequence contains only Unicode letters, digits
- * or space ({@code ' '}).
- *
- * {@code null} will return {@code false}.
- * An empty CharSequence (length()=0) will return {@code true}.
- *
- *
- * StringUtils.isAlphanumericSpace(null) = false
- * StringUtils.isAlphanumericSpace("") = true
- * StringUtils.isAlphanumericSpace(" ") = true
- * StringUtils.isAlphanumericSpace("abc") = true
- * StringUtils.isAlphanumericSpace("ab c") = true
- * StringUtils.isAlphanumericSpace("ab2c") = true
- * StringUtils.isAlphanumericSpace("ab-c") = false
- *
- *
- * @param cs the CharSequence to check, may be null
- * @return {@code true} if only contains letters, digits or space,
- * and is non-null
- * @since 3.0 Changed signature from isAlphanumericSpace(String) to isAlphanumericSpace(CharSequence)
- */
- public static boolean isAlphanumericSpace(CharSequence cs) {
- if (cs == null) {
- return false;
- }
- int sz = cs.length();
- for (int i = 0; i < sz; i++) {
- if (Character.isLetterOrDigit(cs.charAt(i)) == false && cs.charAt(i) != ' ') {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Checks if the CharSequence contains only ASCII printable characters.
- *
- * {@code null} will return {@code false}.
- * An empty CharSequence (length()=0) will return {@code true}.
- *
- *
- * StringUtils.isAsciiPrintable(null) = false
- * StringUtils.isAsciiPrintable("") = true
- * StringUtils.isAsciiPrintable(" ") = true
- * StringUtils.isAsciiPrintable("Ceki") = true
- * StringUtils.isAsciiPrintable("ab2c") = true
- * StringUtils.isAsciiPrintable("!ab-c~") = true
- * StringUtils.isAsciiPrintable("\u0020") = true
- * StringUtils.isAsciiPrintable("\u0021") = true
- * StringUtils.isAsciiPrintable("\u007e") = true
- * StringUtils.isAsciiPrintable("\u007f") = false
- * StringUtils.isAsciiPrintable("Ceki G\u00fclc\u00fc") = false
- *
- *
- * @param cs the CharSequence to check, may be null
- * @return {@code true} if every character is in the range
- * 32 thru 126
- * @since 2.1
- * @since 3.0 Changed signature from isAsciiPrintable(String) to isAsciiPrintable(CharSequence)
- */
- public static boolean isAsciiPrintable(CharSequence cs) {
- if (cs == null) {
- return false;
- }
- int sz = cs.length();
- for (int i = 0; i < sz; i++) {
- if (CharUtils.isAsciiPrintable(cs.charAt(i)) == false) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Checks if the CharSequence contains only Unicode digits.
- * A decimal point is not a Unicode digit and returns false.
- *
- * {@code null} will return {@code false}.
- * An empty CharSequence (length()=0) will return {@code false}.
- *
- *
- * StringUtils.isNumeric(null) = false
- * StringUtils.isNumeric("") = false
- * StringUtils.isNumeric(" ") = false
- * StringUtils.isNumeric("123") = true
- * StringUtils.isNumeric("12 3") = false
- * StringUtils.isNumeric("ab2c") = false
- * StringUtils.isNumeric("12-3") = false
- * StringUtils.isNumeric("12.3") = false
- *
- *
- * @param cs the CharSequence to check, may be null
- * @return {@code true} if only contains digits, and is non-null
- * @since 3.0 Changed signature from isNumeric(String) to isNumeric(CharSequence)
- * @since 3.0 Changed "" to return false and not true
- */
- public static boolean isNumeric(CharSequence cs) {
- if (cs == null || cs.length() == 0) {
- return false;
- }
- int sz = cs.length();
- for (int i = 0; i < sz; i++) {
- if (Character.isDigit(cs.charAt(i)) == false) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Checks if the CharSequence contains only Unicode digits or space
- * ({@code ' '}).
- * A decimal point is not a Unicode digit and returns false.
- *
- * {@code null} will return {@code false}.
- * An empty CharSequence (length()=0) will return {@code true}.
- *
- *
- * StringUtils.isNumericSpace(null) = false
- * StringUtils.isNumericSpace("") = true
- * StringUtils.isNumericSpace(" ") = true
- * StringUtils.isNumericSpace("123") = true
- * StringUtils.isNumericSpace("12 3") = true
- * StringUtils.isNumericSpace("ab2c") = false
- * StringUtils.isNumericSpace("12-3") = false
- * StringUtils.isNumericSpace("12.3") = false
- *
- *
- * @param cs the CharSequence to check, may be null
- * @return {@code true} if only contains digits or space,
- * and is non-null
- * @since 3.0 Changed signature from isNumericSpace(String) to isNumericSpace(CharSequence)
- */
- public static boolean isNumericSpace(CharSequence cs) {
- if (cs == null) {
- return false;
- }
- int sz = cs.length();
- for (int i = 0; i < sz; i++) {
- if (Character.isDigit(cs.charAt(i)) == false && cs.charAt(i) != ' ') {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Checks if the CharSequence contains only whitespace.
- *
- * {@code null} will return {@code false}.
- * An empty CharSequence (length()=0) will return {@code true}.
- *
- *
- * StringUtils.isWhitespace(null) = false
- * StringUtils.isWhitespace("") = true
- * StringUtils.isWhitespace(" ") = true
- * StringUtils.isWhitespace("abc") = false
- * StringUtils.isWhitespace("ab2c") = false
- * StringUtils.isWhitespace("ab-c") = false
- *
- *
- * @param cs the CharSequence to check, may be null
- * @return {@code true} if only contains whitespace, and is non-null
- * @since 2.0
- * @since 3.0 Changed signature from isWhitespace(String) to isWhitespace(CharSequence)
- */
- public static boolean isWhitespace(CharSequence cs) {
- if (cs == null) {
- return false;
- }
- int sz = cs.length();
- for (int i = 0; i < sz; i++) {
- if (Character.isWhitespace(cs.charAt(i)) == false) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Checks if the CharSequence contains only lowercase characters.
- *
- * {@code null} will return {@code false}.
- * An empty CharSequence (length()=0) will return {@code false}.
- *
- *
- * StringUtils.isAllLowerCase(null) = false
- * StringUtils.isAllLowerCase("") = false
- * StringUtils.isAllLowerCase(" ") = false
- * StringUtils.isAllLowerCase("abc") = true
- * StringUtils.isAllLowerCase("abC") = false
- *
- *
- * @param cs the CharSequence to check, may be null
- * @return {@code true} if only contains lowercase characters, and is non-null
- * @since 2.5
- * @since 3.0 Changed signature from isAllLowerCase(String) to isAllLowerCase(CharSequence)
- */
- public static boolean isAllLowerCase(CharSequence cs) {
- if (cs == null || isEmpty(cs)) {
- return false;
- }
- int sz = cs.length();
- for (int i = 0; i < sz; i++) {
- if (Character.isLowerCase(cs.charAt(i)) == false) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Checks if the CharSequence contains only uppercase characters.
- *
- * {@code null} will return {@code false}.
- * An empty String (length()=0) will return {@code false}.
- *
- *
- * StringUtils.isAllUpperCase(null) = false
- * StringUtils.isAllUpperCase("") = false
- * StringUtils.isAllUpperCase(" ") = false
- * StringUtils.isAllUpperCase("ABC") = true
- * StringUtils.isAllUpperCase("aBC") = false
- *
- *
- * @param cs the CharSequence to check, may be null
- * @return {@code true} if only contains uppercase characters, and is non-null
- * @since 2.5
- * @since 3.0 Changed signature from isAllUpperCase(String) to isAllUpperCase(CharSequence)
- */
- public static boolean isAllUpperCase(CharSequence cs) {
- if (cs == null || isEmpty(cs)) {
- return false;
- }
- int sz = cs.length();
- for (int i = 0; i < sz; i++) {
- if (Character.isUpperCase(cs.charAt(i)) == false) {
- return false;
- }
- }
- return true;
- }
-
- // Defaults
- //-----------------------------------------------------------------------
- /**
- * Returns either the passed in String,
- * or if the String is {@code null}, an empty String ("").
- *
- *
- * StringUtils.defaultString(null) = ""
- * StringUtils.defaultString("") = ""
- * StringUtils.defaultString("bat") = "bat"
- *
- *
- * @see ObjectUtils#toString(Object)
- * @see String#valueOf(Object)
- * @param str the String to check, may be null
- * @return the passed in String, or the empty String if it
- * was {@code null}
- */
- public static String defaultString(String str) {
- return str == null ? EMPTY : str;
- }
-
- /**
- * Returns either the passed in String, or if the String is
- * {@code null}, the value of {@code defaultStr}.
- *
- *
- * StringUtils.defaultString(null, "NULL") = "NULL"
- * StringUtils.defaultString("", "NULL") = ""
- * StringUtils.defaultString("bat", "NULL") = "bat"
- *
- *
- * @see ObjectUtils#toString(Object,String)
- * @see String#valueOf(Object)
- * @param str the String to check, may be null
- * @param defaultStr the default String to return
- * if the input is {@code null}, may be null
- * @return the passed in String, or the default if it was {@code null}
- */
- public static String defaultString(String str, String defaultStr) {
- return str == null ? defaultStr : str;
- }
-
- /**
- * Returns either the passed in CharSequence, or if the CharSequence is
- * whitespace, empty ("") or {@code null}, the value of {@code defaultStr}.
- *
- *
- * StringUtils.defaultIfBlank(null, "NULL") = "NULL"
- * StringUtils.defaultIfBlank("", "NULL") = "NULL"
- * StringUtils.defaultIfBlank(" ", "NULL") = "NULL"
- * StringUtils.defaultIfBlank("bat", "NULL") = "bat"
- * StringUtils.defaultIfBlank("", null) = null
- *
- * @param the specific kind of CharSequence
- * @param str the CharSequence to check, may be null
- * @param defaultStr the default CharSequence to return
- * if the input is whitespace, empty ("") or {@code null}, may be null
- * @return the passed in CharSequence, or the default
- * @see StringUtils#defaultString(String, String)
- */
- public static T defaultIfBlank(T str, T defaultStr) {
- return StringUtils.isBlank(str) ? defaultStr : str;
- }
-
- /**
- * Returns either the passed in CharSequence, or if the CharSequence is
- * empty or {@code null}, the value of {@code defaultStr}.
- *
- *
- * StringUtils.defaultIfEmpty(null, "NULL") = "NULL"
- * StringUtils.defaultIfEmpty("", "NULL") = "NULL"
- * StringUtils.defaultIfEmpty(" ", "NULL") = " "
- * StringUtils.defaultIfEmpty("bat", "NULL") = "bat"
- * StringUtils.defaultIfEmpty("", null) = null
- *
- * @param the specific kind of CharSequence
- * @param str the CharSequence to check, may be null
- * @param defaultStr the default CharSequence to return
- * if the input is empty ("") or {@code null}, may be null
- * @return the passed in CharSequence, or the default
- * @see StringUtils#defaultString(String, String)
- */
- public static T defaultIfEmpty(T str, T defaultStr) {
- return StringUtils.isEmpty(str) ? defaultStr : str;
- }
-
- // Reversing
- //-----------------------------------------------------------------------
- /**
- * Reverses a String as per {@link StringBuilder#reverse()}.
- *
- * A {@code null} String returns {@code null}.
- *
- *
- * StringUtils.reverse(null) = null
- * StringUtils.reverse("") = ""
- * StringUtils.reverse("bat") = "tab"
- *
- *
- * @param str the String to reverse, may be null
- * @return the reversed String, {@code null} if null String input
- */
- public static String reverse(String str) {
- if (str == null) {
- return null;
- }
- return new StringBuilder(str).reverse().toString();
- }
-
- /**
- * Reverses a String that is delimited by a specific character.
- *
- * The Strings between the delimiters are not reversed.
- * Thus java.lang.String becomes String.lang.java (if the delimiter
- * is {@code '.'}).
- *
- *
- * StringUtils.reverseDelimited(null, *) = null
- * StringUtils.reverseDelimited("", *) = ""
- * StringUtils.reverseDelimited("a.b.c", 'x') = "a.b.c"
- * StringUtils.reverseDelimited("a.b.c", ".") = "c.b.a"
- *
- *
- * @param str the String to reverse, may be null
- * @param separatorChar the separator character to use
- * @return the reversed String, {@code null} if null String input
- * @since 2.0
- */
- public static String reverseDelimited(String str, char separatorChar) {
- if (str == null) {
- return null;
- }
- // could implement manually, but simple way is to reuse other,
- // probably slower, methods.
- String[] strs = split(str, separatorChar);
- ArrayUtils.reverse(strs);
- return join(strs, separatorChar);
- }
-
- // Abbreviating
- //-----------------------------------------------------------------------
- /**
- * Abbreviates a String using ellipses. This will turn
- * "Now is the time for all good men" into "Now is the time for..."
- *
- * Specifically:
- *
- * If {@code str} is less than {@code maxWidth} characters
- * long, return it.
- * Else abbreviate it to {@code (substring(str, 0, max-3) + "...")}.
- * If {@code maxWidth} is less than {@code 4}, throw an
- * {@code IllegalArgumentException}.
- * In no case will it return a String of length greater than
- * {@code maxWidth}.
- *
- *
- *
- *
- * StringUtils.abbreviate(null, *) = null
- * StringUtils.abbreviate("", 4) = ""
- * StringUtils.abbreviate("abcdefg", 6) = "abc..."
- * StringUtils.abbreviate("abcdefg", 7) = "abcdefg"
- * StringUtils.abbreviate("abcdefg", 8) = "abcdefg"
- * StringUtils.abbreviate("abcdefg", 4) = "a..."
- * StringUtils.abbreviate("abcdefg", 3) = IllegalArgumentException
- *
- *
- * @param str the String to check, may be null
- * @param maxWidth maximum length of result String, must be at least 4
- * @return abbreviated String, {@code null} if null String input
- * @throws IllegalArgumentException if the width is too small
- * @since 2.0
- */
- public static String abbreviate(String str, int maxWidth) {
- return abbreviate(str, 0, maxWidth);
- }
-
- /**
- * Abbreviates a String using ellipses. This will turn
- * "Now is the time for all good men" into "...is the time for..."
- *
- * Works like {@code abbreviate(String, int)}, but allows you to specify
- * a "left edge" offset. Note that this left edge is not necessarily going to
- * be the leftmost character in the result, or the first character following the
- * ellipses, but it will appear somewhere in the result.
- *
- *
In no case will it return a String of length greater than
- * {@code maxWidth}.
- *
- *
- * StringUtils.abbreviate(null, *, *) = null
- * StringUtils.abbreviate("", 0, 4) = ""
- * StringUtils.abbreviate("abcdefghijklmno", -1, 10) = "abcdefg..."
- * StringUtils.abbreviate("abcdefghijklmno", 0, 10) = "abcdefg..."
- * StringUtils.abbreviate("abcdefghijklmno", 1, 10) = "abcdefg..."
- * StringUtils.abbreviate("abcdefghijklmno", 4, 10) = "abcdefg..."
- * StringUtils.abbreviate("abcdefghijklmno", 5, 10) = "...fghi..."
- * StringUtils.abbreviate("abcdefghijklmno", 6, 10) = "...ghij..."
- * StringUtils.abbreviate("abcdefghijklmno", 8, 10) = "...ijklmno"
- * StringUtils.abbreviate("abcdefghijklmno", 10, 10) = "...ijklmno"
- * StringUtils.abbreviate("abcdefghijklmno", 12, 10) = "...ijklmno"
- * StringUtils.abbreviate("abcdefghij", 0, 3) = IllegalArgumentException
- * StringUtils.abbreviate("abcdefghij", 5, 6) = IllegalArgumentException
- *
- *
- * @param str the String to check, may be null
- * @param offset left edge of source String
- * @param maxWidth maximum length of result String, must be at least 4
- * @return abbreviated String, {@code null} if null String input
- * @throws IllegalArgumentException if the width is too small
- * @since 2.0
- */
- public static String abbreviate(String str, int offset, int maxWidth) {
- if (str == null) {
- return null;
- }
- if (maxWidth < 4) {
- throw new IllegalArgumentException("Minimum abbreviation width is 4");
- }
- if (str.length() <= maxWidth) {
- return str;
- }
- if (offset > str.length()) {
- offset = str.length();
- }
- if (str.length() - offset < maxWidth - 3) {
- offset = str.length() - (maxWidth - 3);
- }
- final String abrevMarker = "...";
- if (offset <= 4) {
- return str.substring(0, maxWidth - 3) + abrevMarker;
- }
- if (maxWidth < 7) {
- throw new IllegalArgumentException("Minimum abbreviation width with offset is 7");
- }
- if (offset + maxWidth - 3 < str.length()) {
- return abrevMarker + abbreviate(str.substring(offset), maxWidth - 3);
- }
- return abrevMarker + str.substring(str.length() - (maxWidth - 3));
- }
-
- /**
- * Abbreviates a String to the length passed, replacing the middle characters with the supplied
- * replacement String.
- *
- * This abbreviation only occurs if the following criteria is met:
- *
- * Neither the String for abbreviation nor the replacement String are null or empty
- * The length to truncate to is less than the length of the supplied String
- * The length to truncate to is greater than 0
- * The abbreviated String will have enough room for the length supplied replacement String
- * and the first and last characters of the supplied String for abbreviation
- *
- * Otherwise, the returned String will be the same as the supplied String for abbreviation.
- *
- *
- *
- * StringUtils.abbreviateMiddle(null, null, 0) = null
- * StringUtils.abbreviateMiddle("abc", null, 0) = "abc"
- * StringUtils.abbreviateMiddle("abc", ".", 0) = "abc"
- * StringUtils.abbreviateMiddle("abc", ".", 3) = "abc"
- * StringUtils.abbreviateMiddle("abcdef", ".", 4) = "ab.f"
- *
- *
- * @param str the String to abbreviate, may be null
- * @param middle the String to replace the middle characters with, may be null
- * @param length the length to abbreviate {@code str} to.
- * @return the abbreviated String if the above criteria is met, or the original String supplied for abbreviation.
- * @since 2.5
- */
- public static String abbreviateMiddle(String str, String middle, int length) {
- if (isEmpty(str) || isEmpty(middle)) {
- return str;
- }
-
- if (length >= str.length() || length < middle.length()+2) {
- return str;
- }
-
- int targetSting = length-middle.length();
- int startOffset = targetSting/2+targetSting%2;
- int endOffset = str.length()-targetSting/2;
-
- StringBuilder builder = new StringBuilder(length);
- builder.append(str.substring(0,startOffset));
- builder.append(middle);
- builder.append(str.substring(endOffset));
-
- return builder.toString();
- }
-
- // Difference
- //-----------------------------------------------------------------------
- /**
- * Compares two Strings, and returns the portion where they differ.
- * (More precisely, return the remainder of the second String,
- * starting from where it's different from the first.)
- *
- * For example,
- * {@code difference("i am a machine", "i am a robot") -> "robot"}.
- *
- *
- * StringUtils.difference(null, null) = null
- * StringUtils.difference("", "") = ""
- * StringUtils.difference("", "abc") = "abc"
- * StringUtils.difference("abc", "") = ""
- * StringUtils.difference("abc", "abc") = ""
- * StringUtils.difference("ab", "abxyz") = "xyz"
- * StringUtils.difference("abcde", "abxyz") = "xyz"
- * StringUtils.difference("abcde", "xyz") = "xyz"
- *
- *
- * @param str1 the first String, may be null
- * @param str2 the second String, may be null
- * @return the portion of str2 where it differs from str1; returns the
- * empty String if they are equal
- * @since 2.0
- */
- public static String difference(String str1, String str2) {
- if (str1 == null) {
- return str2;
- }
- if (str2 == null) {
- return str1;
- }
- int at = indexOfDifference(str1, str2);
- if (at == INDEX_NOT_FOUND) {
- return EMPTY;
- }
- return str2.substring(at);
- }
-
- /**
- * Compares two CharSequences, and returns the index at which the
- * CharSequences begin to differ.
- *
- * For example,
- * {@code indexOfDifference("i am a machine", "i am a robot") -> 7}
- *
- *
- * StringUtils.indexOfDifference(null, null) = -1
- * StringUtils.indexOfDifference("", "") = -1
- * StringUtils.indexOfDifference("", "abc") = 0
- * StringUtils.indexOfDifference("abc", "") = 0
- * StringUtils.indexOfDifference("abc", "abc") = -1
- * StringUtils.indexOfDifference("ab", "abxyz") = 2
- * StringUtils.indexOfDifference("abcde", "abxyz") = 2
- * StringUtils.indexOfDifference("abcde", "xyz") = 0
- *
- *
- * @param cs1 the first CharSequence, may be null
- * @param cs2 the second CharSequence, may be null
- * @return the index where cs1 and cs2 begin to differ; -1 if they are equal
- * @since 2.0
- * @since 3.0 Changed signature from indexOfDifference(String, String) to
- * indexOfDifference(CharSequence, CharSequence)
- */
- public static int indexOfDifference(CharSequence cs1, CharSequence cs2) {
- if (cs1 == cs2) {
- return INDEX_NOT_FOUND;
- }
- if (cs1 == null || cs2 == null) {
- return 0;
- }
- int i;
- for (i = 0; i < cs1.length() && i < cs2.length(); ++i) {
- if (cs1.charAt(i) != cs2.charAt(i)) {
- break;
- }
- }
- if (i < cs2.length() || i < cs1.length()) {
- return i;
- }
- return INDEX_NOT_FOUND;
- }
-
- /**
- * Compares all CharSequences in an array and returns the index at which the
- * CharSequences begin to differ.
- *
- * For example,
- * indexOfDifference(new String[] {"i am a machine", "i am a robot"}) -> 7
- *
- *
- * StringUtils.indexOfDifference(null) = -1
- * StringUtils.indexOfDifference(new String[] {}) = -1
- * StringUtils.indexOfDifference(new String[] {"abc"}) = -1
- * StringUtils.indexOfDifference(new String[] {null, null}) = -1
- * StringUtils.indexOfDifference(new String[] {"", ""}) = -1
- * StringUtils.indexOfDifference(new String[] {"", null}) = 0
- * StringUtils.indexOfDifference(new String[] {"abc", null, null}) = 0
- * StringUtils.indexOfDifference(new String[] {null, null, "abc"}) = 0
- * StringUtils.indexOfDifference(new String[] {"", "abc"}) = 0
- * StringUtils.indexOfDifference(new String[] {"abc", ""}) = 0
- * StringUtils.indexOfDifference(new String[] {"abc", "abc"}) = -1
- * StringUtils.indexOfDifference(new String[] {"abc", "a"}) = 1
- * StringUtils.indexOfDifference(new String[] {"ab", "abxyz"}) = 2
- * StringUtils.indexOfDifference(new String[] {"abcde", "abxyz"}) = 2
- * StringUtils.indexOfDifference(new String[] {"abcde", "xyz"}) = 0
- * StringUtils.indexOfDifference(new String[] {"xyz", "abcde"}) = 0
- * StringUtils.indexOfDifference(new String[] {"i am a machine", "i am a robot"}) = 7
- *
- *
- * @param css array of CharSequences, entries may be null
- * @return the index where the strings begin to differ; -1 if they are all equal
- * @since 2.4
- * @since 3.0 Changed signature from indexOfDifference(String...) to indexOfDifference(CharSequence...)
- */
- public static int indexOfDifference(CharSequence... css) {
- if (css == null || css.length <= 1) {
- return INDEX_NOT_FOUND;
- }
- boolean anyStringNull = false;
- boolean allStringsNull = true;
- int arrayLen = css.length;
- int shortestStrLen = Integer.MAX_VALUE;
- int longestStrLen = 0;
-
- // find the min and max string lengths; this avoids checking to make
- // sure we are not exceeding the length of the string each time through
- // the bottom loop.
- for (int i = 0; i < arrayLen; i++) {
- if (css[i] == null) {
- anyStringNull = true;
- shortestStrLen = 0;
- } else {
- allStringsNull = false;
- shortestStrLen = Math.min(css[i].length(), shortestStrLen);
- longestStrLen = Math.max(css[i].length(), longestStrLen);
- }
- }
-
- // handle lists containing all nulls or all empty strings
- if (allStringsNull || longestStrLen == 0 && !anyStringNull) {
- return INDEX_NOT_FOUND;
- }
-
- // handle lists containing some nulls or some empty strings
- if (shortestStrLen == 0) {
- return 0;
- }
-
- // find the position with the first difference across all strings
- int firstDiff = -1;
- for (int stringPos = 0; stringPos < shortestStrLen; stringPos++) {
- char comparisonChar = css[0].charAt(stringPos);
- for (int arrayPos = 1; arrayPos < arrayLen; arrayPos++) {
- if (css[arrayPos].charAt(stringPos) != comparisonChar) {
- firstDiff = stringPos;
- break;
- }
- }
- if (firstDiff != -1) {
- break;
- }
- }
-
- if (firstDiff == -1 && shortestStrLen != longestStrLen) {
- // we compared all of the characters up to the length of the
- // shortest string and didn't find a match, but the string lengths
- // vary, so return the length of the shortest string.
- return shortestStrLen;
- }
- return firstDiff;
- }
-
- /**
- * Compares all Strings in an array and returns the initial sequence of
- * characters that is common to all of them.
- *
- * For example,
- * getCommonPrefix(new String[] {"i am a machine", "i am a robot"}) -> "i am a "
- *
- *
- * StringUtils.getCommonPrefix(null) = ""
- * StringUtils.getCommonPrefix(new String[] {}) = ""
- * StringUtils.getCommonPrefix(new String[] {"abc"}) = "abc"
- * StringUtils.getCommonPrefix(new String[] {null, null}) = ""
- * StringUtils.getCommonPrefix(new String[] {"", ""}) = ""
- * StringUtils.getCommonPrefix(new String[] {"", null}) = ""
- * StringUtils.getCommonPrefix(new String[] {"abc", null, null}) = ""
- * StringUtils.getCommonPrefix(new String[] {null, null, "abc"}) = ""
- * StringUtils.getCommonPrefix(new String[] {"", "abc"}) = ""
- * StringUtils.getCommonPrefix(new String[] {"abc", ""}) = ""
- * StringUtils.getCommonPrefix(new String[] {"abc", "abc"}) = "abc"
- * StringUtils.getCommonPrefix(new String[] {"abc", "a"}) = "a"
- * StringUtils.getCommonPrefix(new String[] {"ab", "abxyz"}) = "ab"
- * StringUtils.getCommonPrefix(new String[] {"abcde", "abxyz"}) = "ab"
- * StringUtils.getCommonPrefix(new String[] {"abcde", "xyz"}) = ""
- * StringUtils.getCommonPrefix(new String[] {"xyz", "abcde"}) = ""
- * StringUtils.getCommonPrefix(new String[] {"i am a machine", "i am a robot"}) = "i am a "
- *
- *
- * @param strs array of String objects, entries may be null
- * @return the initial sequence of characters that are common to all Strings
- * in the array; empty String if the array is null, the elements are all null
- * or if there is no common prefix.
- * @since 2.4
- */
- public static String getCommonPrefix(String... strs) {
- if (strs == null || strs.length == 0) {
- return EMPTY;
- }
- int smallestIndexOfDiff = indexOfDifference(strs);
- if (smallestIndexOfDiff == INDEX_NOT_FOUND) {
- // all strings were identical
- if (strs[0] == null) {
- return EMPTY;
- }
- return strs[0];
- } else if (smallestIndexOfDiff == 0) {
- // there were no common initial characters
- return EMPTY;
- } else {
- // we found a common initial character sequence
- return strs[0].substring(0, smallestIndexOfDiff);
- }
- }
-
- // Misc
- //-----------------------------------------------------------------------
- /**
- * Find the Levenshtein distance between two Strings.
- *
- * This is the number of changes needed to change one String into
- * another, where each change is a single character modification (deletion,
- * insertion or substitution).
- *
- * The previous implementation of the Levenshtein distance algorithm
- * was from http://www.merriampark.com/ld.htm
- *
- * Chas Emerick has written an implementation in Java, which avoids an OutOfMemoryError
- * which can occur when my Java implementation is used with very large strings.
- * This implementation of the Levenshtein distance algorithm
- * is from http://www.merriampark.com/ldjava.htm
- *
- *
- * StringUtils.getLevenshteinDistance(null, *) = IllegalArgumentException
- * StringUtils.getLevenshteinDistance(*, null) = IllegalArgumentException
- * StringUtils.getLevenshteinDistance("","") = 0
- * StringUtils.getLevenshteinDistance("","a") = 1
- * StringUtils.getLevenshteinDistance("aaapppp", "") = 7
- * StringUtils.getLevenshteinDistance("frog", "fog") = 1
- * StringUtils.getLevenshteinDistance("fly", "ant") = 3
- * StringUtils.getLevenshteinDistance("elephant", "hippo") = 7
- * StringUtils.getLevenshteinDistance("hippo", "elephant") = 7
- * StringUtils.getLevenshteinDistance("hippo", "zzzzzzzz") = 8
- * StringUtils.getLevenshteinDistance("hello", "hallo") = 1
- *
- *
- * @param s the first String, must not be null
- * @param t the second String, must not be null
- * @return result distance
- * @throws IllegalArgumentException if either String input {@code null}
- * @since 3.0 Changed signature from getLevenshteinDistance(String, String) to
- * getLevenshteinDistance(CharSequence, CharSequence)
- */
- public static int getLevenshteinDistance(CharSequence s, CharSequence t) {
- if (s == null || t == null) {
- throw new IllegalArgumentException("Strings must not be null");
- }
-
- /*
- The difference between this impl. and the previous is that, rather
- than creating and retaining a matrix of size s.length() + 1 by t.length() + 1,
- we maintain two single-dimensional arrays of length s.length() + 1. The first, d,
- is the 'current working' distance array that maintains the newest distance cost
- counts as we iterate through the characters of String s. Each time we increment
- the index of String t we are comparing, d is copied to p, the second int[]. Doing so
- allows us to retain the previous cost counts as required by the algorithm (taking
- the minimum of the cost count to the left, up one, and diagonally up and to the left
- of the current cost count being calculated). (Note that the arrays aren't really
- copied anymore, just switched...this is clearly much better than cloning an array
- or doing a System.arraycopy() each time through the outer loop.)
-
- Effectively, the difference between the two implementations is this one does not
- cause an out of memory condition when calculating the LD over two very large strings.
- */
-
- int n = s.length(); // length of s
- int m = t.length(); // length of t
-
- if (n == 0) {
- return m;
- } else if (m == 0) {
- return n;
- }
-
- if (n > m) {
- // swap the input strings to consume less memory
- CharSequence tmp = s;
- s = t;
- t = tmp;
- n = m;
- m = t.length();
- }
-
- int p[] = new int[n + 1]; //'previous' cost array, horizontally
- int d[] = new int[n + 1]; // cost array, horizontally
- int _d[]; //placeholder to assist in swapping p and d
-
- // indexes into strings s and t
- int i; // iterates through s
- int j; // iterates through t
-
- char t_j; // jth character of t
-
- int cost; // cost
-
- for (i = 0; i <= n; i++) {
- p[i] = i;
- }
-
- for (j = 1; j <= m; j++) {
- t_j = t.charAt(j - 1);
- d[0] = j;
-
- for (i = 1; i <= n; i++) {
- cost = s.charAt(i - 1) == t_j ? 0 : 1;
- // minimum of cell to the left+1, to the top+1, diagonally left and up +cost
- d[i] = Math.min(Math.min(d[i - 1] + 1, p[i] + 1), p[i - 1] + cost);
- }
-
- // copy current distance counts to 'previous row' distance counts
- _d = p;
- p = d;
- d = _d;
- }
-
- // our last action in the above loop was to switch d and p, so p now
- // actually has the most recent cost counts
- return p[n];
- }
-
- /**
- * Find the Levenshtein distance between two Strings if it's less than or equal to a given
- * threshold.
- *
- * This is the number of changes needed to change one String into
- * another, where each change is a single character modification (deletion,
- * insertion or substitution).
- *
- * This implementation follows from Algorithms on Strings, Trees and Sequences by Dan Gusfield
- * and Chas Emerick's implementation of the Levenshtein distance algorithm from
- * http://www.merriampark.com/ld.htm
- *
- *
- * StringUtils.getLevenshteinDistance(null, *, *) = IllegalArgumentException
- * StringUtils.getLevenshteinDistance(*, null, *) = IllegalArgumentException
- * StringUtils.getLevenshteinDistance(*, *, -1) = IllegalArgumentException
- * StringUtils.getLevenshteinDistance("","", 0) = 0
- * StringUtils.getLevenshteinDistance("aaapppp", "", 8) = 7
- * StringUtils.getLevenshteinDistance("aaapppp", "", 7) = 7
- * StringUtils.getLevenshteinDistance("aaapppp", "", 6)) = -1
- * StringUtils.getLevenshteinDistance("elephant", "hippo", 7) = 7
- * StringUtils.getLevenshteinDistance("elephant", "hippo", 6) = -1
- * StringUtils.getLevenshteinDistance("hippo", "elephant", 7) = 7
- * StringUtils.getLevenshteinDistance("hippo", "elephant", 6) = -1
- *
- *
- * @param s the first String, must not be null
- * @param t the second String, must not be null
- * @param threshold the target threshold, must not be negative
- * @return result distance, or {@code -1} if the distance would be greater than the threshold
- * @throws IllegalArgumentException if either String input {@code null} or negative threshold
- */
- public static int getLevenshteinDistance(CharSequence s, CharSequence t, int threshold) {
- if (s == null || t == null) {
- throw new IllegalArgumentException("Strings must not be null");
- }
- if (threshold < 0) {
- throw new IllegalArgumentException("Threshold must not be negative");
- }
-
- /*
- This implementation only computes the distance if it's less than or equal to the
- threshold value, returning -1 if it's greater. The advantage is performance: unbounded
- distance is O(nm), but a bound of k allows us to reduce it to O(km) time by only
- computing a diagonal stripe of width 2k + 1 of the cost table.
- It is also possible to use this to compute the unbounded Levenshtein distance by starting
- the threshold at 1 and doubling each time until the distance is found; this is O(dm), where
- d is the distance.
-
- One subtlety comes from needing to ignore entries on the border of our stripe
- eg.
- p[] = |#|#|#|*
- d[] = *|#|#|#|
- We must ignore the entry to the left of the leftmost member
- We must ignore the entry above the rightmost member
-
- Another subtlety comes from our stripe running off the matrix if the strings aren't
- of the same size. Since string s is always swapped to be the shorter of the two,
- the stripe will always run off to the upper right instead of the lower left of the matrix.
-
- As a concrete example, suppose s is of length 5, t is of length 7, and our threshold is 1.
- In this case we're going to walk a stripe of length 3. The matrix would look like so:
-
- 1 2 3 4 5
- 1 |#|#| | | |
- 2 |#|#|#| | |
- 3 | |#|#|#| |
- 4 | | |#|#|#|
- 5 | | | |#|#|
- 6 | | | | |#|
- 7 | | | | | |
-
- Note how the stripe leads off the table as there is no possible way to turn a string of length 5
- into one of length 7 in edit distance of 1.
-
- Additionally, this implementation decreases memory usage by using two
- single-dimensional arrays and swapping them back and forth instead of allocating
- an entire n by m matrix. This requires a few minor changes, such as immediately returning
- when it's detected that the stripe has run off the matrix and initially filling the arrays with
- large values so that entries we don't compute are ignored.
-
- See Algorithms on Strings, Trees and Sequences by Dan Gusfield for some discussion.
- */
-
- int n = s.length(); // length of s
- int m = t.length(); // length of t
-
- // if one string is empty, the edit distance is necessarily the length of the other
- if (n == 0) {
- return m <= threshold ? m : -1;
- } else if (m == 0) {
- return n <= threshold ? n : -1;
- }
-
- if (n > m) {
- // swap the two strings to consume less memory
- CharSequence tmp = s;
- s = t;
- t = tmp;
- n = m;
- m = t.length();
- }
-
- int p[] = new int[n + 1]; // 'previous' cost array, horizontally
- int d[] = new int[n + 1]; // cost array, horizontally
- int _d[]; // placeholder to assist in swapping p and d
-
- // fill in starting table values
- int boundary = Math.min(n, threshold) + 1;
- for (int i = 0; i < boundary; i++) {
- p[i] = i;
- }
- // these fills ensure that the value above the rightmost entry of our
- // stripe will be ignored in following loop iterations
- Arrays.fill(p, boundary, p.length, Integer.MAX_VALUE);
- Arrays.fill(d, Integer.MAX_VALUE);
-
- // iterates through t
- for (int j = 1; j <= m; j++) {
- char t_j = t.charAt(j - 1); // jth character of t
- d[0] = j;
-
- // compute stripe indices, constrain to array size
- int min = Math.max(1, j - threshold);
- int max = Math.min(n, j + threshold);
-
- // the stripe may lead off of the table if s and t are of different sizes
- if (min > max) {
- return -1;
- }
-
- // ignore entry left of leftmost
- if (min > 1) {
- d[min - 1] = Integer.MAX_VALUE;
- }
-
- // iterates through [min, max] in s
- for (int i = min; i <= max; i++) {
- if (s.charAt(i - 1) == t_j) {
- // diagonally left and up
- d[i] = p[i - 1];
- } else {
- // 1 + minimum of cell to the left, to the top, diagonally left and up
- d[i] = 1 + Math.min(Math.min(d[i - 1], p[i]), p[i - 1]);
- }
- }
-
- // copy current distance counts to 'previous row' distance counts
- _d = p;
- p = d;
- d = _d;
- }
-
- // if p[n] is greater than the threshold, there's no guarantee on it being the correct
- // distance
- if (p[n] <= threshold) {
- return p[n];
- } else {
- return -1;
- }
- }
-
- // startsWith
- //-----------------------------------------------------------------------
-
- /**
- * Check if a CharSequence starts with a specified prefix.
- *
- * {@code null}s are handled without exceptions. Two {@code null}
- * references are considered to be equal. The comparison is case sensitive.
- *
- *
- * StringUtils.startsWith(null, null) = true
- * StringUtils.startsWith(null, "abc") = false
- * StringUtils.startsWith("abcdef", null) = false
- * StringUtils.startsWith("abcdef", "abc") = true
- * StringUtils.startsWith("ABCDEF", "abc") = false
- *
- *
- * @see java.lang.String#startsWith(String)
- * @param str the CharSequence to check, may be null
- * @param prefix the prefix to find, may be null
- * @return {@code true} if the CharSequence starts with the prefix, case sensitive, or
- * both {@code null}
- * @since 2.4
- * @since 3.0 Changed signature from startsWith(String, String) to startsWith(CharSequence, CharSequence)
- */
- public static boolean startsWith(CharSequence str, CharSequence prefix) {
- return startsWith(str, prefix, false);
- }
-
- /**
- * Case insensitive check if a CharSequence starts with a specified prefix.
- *
- * {@code null}s are handled without exceptions. Two {@code null}
- * references are considered to be equal. The comparison is case insensitive.
- *
- *
- * StringUtils.startsWithIgnoreCase(null, null) = true
- * StringUtils.startsWithIgnoreCase(null, "abc") = false
- * StringUtils.startsWithIgnoreCase("abcdef", null) = false
- * StringUtils.startsWithIgnoreCase("abcdef", "abc") = true
- * StringUtils.startsWithIgnoreCase("ABCDEF", "abc") = true
- *
- *
- * @see java.lang.String#startsWith(String)
- * @param str the CharSequence to check, may be null
- * @param prefix the prefix to find, may be null
- * @return {@code true} if the CharSequence starts with the prefix, case insensitive, or
- * both {@code null}
- * @since 2.4
- * @since 3.0 Changed signature from startsWithIgnoreCase(String, String) to startsWithIgnoreCase(CharSequence, CharSequence)
- */
- public static boolean startsWithIgnoreCase(CharSequence str, CharSequence prefix) {
- return startsWith(str, prefix, true);
- }
-
- /**
- * Check if a CharSequence starts with a specified prefix (optionally case insensitive).
- *
- * @see java.lang.String#startsWith(String)
- * @param str the CharSequence to check, may be null
- * @param prefix the prefix to find, may be null
- * @param ignoreCase indicates whether the compare should ignore case
- * (case insensitive) or not.
- * @return {@code true} if the CharSequence starts with the prefix or
- * both {@code null}
- */
- private static boolean startsWith(CharSequence str, CharSequence prefix, boolean ignoreCase) {
- if (str == null || prefix == null) {
- return str == null && prefix == null;
- }
- if (prefix.length() > str.length()) {
- return false;
- }
- return CharSequenceUtils.regionMatches(str, ignoreCase, 0, prefix, 0, prefix.length());
- }
-
- /**
- * Check if a CharSequence starts with any of an array of specified strings.
- *
- *
- * StringUtils.startsWithAny(null, null) = false
- * StringUtils.startsWithAny(null, new String[] {"abc"}) = false
- * StringUtils.startsWithAny("abcxyz", null) = false
- * StringUtils.startsWithAny("abcxyz", new String[] {""}) = false
- * StringUtils.startsWithAny("abcxyz", new String[] {"abc"}) = true
- * StringUtils.startsWithAny("abcxyz", new String[] {null, "xyz", "abc"}) = true
- *
- *
- * @param string the CharSequence to check, may be null
- * @param searchStrings the CharSequences to find, may be null or empty
- * @return {@code true} if the CharSequence starts with any of the the prefixes, case insensitive, or
- * both {@code null}
- * @since 2.5
- * @since 3.0 Changed signature from startsWithAny(String, String[]) to startsWithAny(CharSequence, CharSequence...)
- */
- public static boolean startsWithAny(CharSequence string, CharSequence... searchStrings) {
- if (isEmpty(string) || ArrayUtils.isEmpty(searchStrings)) {
- return false;
- }
- for (CharSequence searchString : searchStrings) {
- if (StringUtils.startsWith(string, searchString)) {
- return true;
- }
- }
- return false;
- }
-
- // endsWith
- //-----------------------------------------------------------------------
-
- /**
- * Check if a CharSequence ends with a specified suffix.
- *
- * {@code null}s are handled without exceptions. Two {@code null}
- * references are considered to be equal. The comparison is case sensitive.
- *
- *
- * StringUtils.endsWith(null, null) = true
- * StringUtils.endsWith(null, "def") = false
- * StringUtils.endsWith("abcdef", null) = false
- * StringUtils.endsWith("abcdef", "def") = true
- * StringUtils.endsWith("ABCDEF", "def") = false
- * StringUtils.endsWith("ABCDEF", "cde") = false
- *
- *
- * @see java.lang.String#endsWith(String)
- * @param str the CharSequence to check, may be null
- * @param suffix the suffix to find, may be null
- * @return {@code true} if the CharSequence ends with the suffix, case sensitive, or
- * both {@code null}
- * @since 2.4
- * @since 3.0 Changed signature from endsWith(String, String) to endsWith(CharSequence, CharSequence)
- */
- public static boolean endsWith(CharSequence str, CharSequence suffix) {
- return endsWith(str, suffix, false);
- }
-
- /**
- * Case insensitive check if a CharSequence ends with a specified suffix.
- *
- * {@code null}s are handled without exceptions. Two {@code null}
- * references are considered to be equal. The comparison is case insensitive.
- *
- *
- * StringUtils.endsWithIgnoreCase(null, null) = true
- * StringUtils.endsWithIgnoreCase(null, "def") = false
- * StringUtils.endsWithIgnoreCase("abcdef", null) = false
- * StringUtils.endsWithIgnoreCase("abcdef", "def") = true
- * StringUtils.endsWithIgnoreCase("ABCDEF", "def") = true
- * StringUtils.endsWithIgnoreCase("ABCDEF", "cde") = false
- *
- *
- * @see java.lang.String#endsWith(String)
- * @param str the CharSequence to check, may be null
- * @param suffix the suffix to find, may be null
- * @return {@code true} if the CharSequence ends with the suffix, case insensitive, or
- * both {@code null}
- * @since 2.4
- * @since 3.0 Changed signature from endsWithIgnoreCase(String, String) to endsWithIgnoreCase(CharSequence, CharSequence)
- */
- public static boolean endsWithIgnoreCase(CharSequence str, CharSequence suffix) {
- return endsWith(str, suffix, true);
- }
-
- /**
- * Check if a CharSequence ends with a specified suffix (optionally case insensitive).
- *
- * @see java.lang.String#endsWith(String)
- * @param str the CharSequence to check, may be null
- * @param suffix the suffix to find, may be null
- * @param ignoreCase indicates whether the compare should ignore case
- * (case insensitive) or not.
- * @return {@code true} if the CharSequence starts with the prefix or
- * both {@code null}
- */
- private static boolean endsWith(CharSequence str, CharSequence suffix, boolean ignoreCase) {
- if (str == null || suffix == null) {
- return str == null && suffix == null;
- }
- if (suffix.length() > str.length()) {
- return false;
- }
- int strOffset = str.length() - suffix.length();
- return CharSequenceUtils.regionMatches(str, ignoreCase, strOffset, suffix, 0, suffix.length());
- }
-
- /**
- *
- * Similar to http://www.w3.org/TR/xpath/#function-normalize
- * -space
- *
- *
- * The function returns the argument string with whitespace normalized by using
- * {@link #trim(String)} to remove leading and trailing whitespace
- * and then replacing sequences of whitespace characters by a single space.
- *
- * In XML Whitespace characters are the same as those allowed by the S production, which is S ::= (#x20 | #x9 | #xD | #xA)+
- *
- * Java's regexp pattern \s defines whitespace as [ \t\n\x0B\f\r]
- *
- * For reference:
- *
- * \x0B = vertical tab
- * \f = #xC = form feed
- * #x20 = space
- * #x9 = \t
- * #xA = \n
- * #xD = \r
- *
- *
- *
- * The difference is that Java's whitespace includes vertical tab and form feed, which this functional will also
- * normalize. Additionally {@link #trim(String)} removes control characters (char <= 32) from both
- * ends of this String.
- *
- *
- * @see Pattern
- * @see #trim(String)
- * @see http://www.w3.org/TR/xpath/#function-normalize-space
- * @param str the source String to normalize whitespaces from, may be null
- * @return the modified string with whitespace normalized, {@code null} if null String input
- *
- * @since 3.0
- */
- public static String normalizeSpace(String str) {
- if (str == null) {
- return null;
- }
- return WHITESPACE_BLOCK.matcher(trim(str)).replaceAll(" ");
- }
-
- /**
- * Check if a CharSequence ends with any of an array of specified strings.
- *
- *
- * StringUtils.endsWithAny(null, null) = false
- * StringUtils.endsWithAny(null, new String[] {"abc"}) = false
- * StringUtils.endsWithAny("abcxyz", null) = false
- * StringUtils.endsWithAny("abcxyz", new String[] {""}) = true
- * StringUtils.endsWithAny("abcxyz", new String[] {"xyz"}) = true
- * StringUtils.endsWithAny("abcxyz", new String[] {null, "xyz", "abc"}) = true
- *
- *
- * @param string the CharSequence to check, may be null
- * @param searchStrings the CharSequences to find, may be null or empty
- * @return {@code true} if the CharSequence ends with any of the the prefixes, case insensitive, or
- * both {@code null}
- * @since 3.0
- */
- public static boolean endsWithAny(CharSequence string, CharSequence... searchStrings) {
- if (isEmpty(string) || ArrayUtils.isEmpty(searchStrings)) {
- return false;
- }
- for (CharSequence searchString : searchStrings) {
- if (StringUtils.endsWith(string, searchString)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Converts a byte[] to a String using the specified character encoding.
- *
- * @param bytes
- * the byte array to read from
- * @param charsetName
- * the encoding to use, if null then use the platform default
- * @return a new String
- * @throws UnsupportedEncodingException
- * If the named charset is not supported
- * @throws NullPointerException
- * if the input is null
- * @since 3.1
- */
- public static String toString(byte[] bytes, String charsetName) throws UnsupportedEncodingException {
- return charsetName == null ? new String(bytes) : new String(bytes, charsetName);
- }
-
-}
diff --git a/core/src/main/java/external/org/apache/commons/lang3/SystemUtils.java b/core/src/main/java/external/org/apache/commons/lang3/SystemUtils.java
deleted file mode 100644
index e6a1c10f..00000000
--- a/core/src/main/java/external/org/apache/commons/lang3/SystemUtils.java
+++ /dev/null
@@ -1,1443 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package external.org.apache.commons.lang3;
-
-import java.io.File;
-
-/**
- *
- * Helpers for {@code java.lang.System}.
- *
- *
- * If a system property cannot be read due to security restrictions, the corresponding field in this class will be set
- * to {@code null} and a message will be written to {@code System.err}.
- *
- *
- * #ThreadSafe#
- *
- *
- * @since 1.0
- * @version $Id: SystemUtils.java 1199816 2011-11-09 16:11:34Z bayard $
- */
-public class SystemUtils {
-
- /**
- * The prefix String for all Windows OS.
- */
- private static final String OS_NAME_WINDOWS_PREFIX = "Windows";
-
- // System property constants
- // -----------------------------------------------------------------------
- // These MUST be declared first. Other constants depend on this.
-
- /**
- * The System property key for the user home directory.
- */
- private static final String USER_HOME_KEY = "user.home";
-
- /**
- * The System property key for the user directory.
- */
- private static final String USER_DIR_KEY = "user.dir";
-
- /**
- * The System property key for the Java IO temporary directory.
- */
- private static final String JAVA_IO_TMPDIR_KEY = "java.io.tmpdir";
-
- /**
- * The System property key for the Java home directory.
- */
- private static final String JAVA_HOME_KEY = "java.home";
-
- /**
- *
- * The {@code awt.toolkit} System Property.
- *
- *
- * Holds a class name, on Windows XP this is {@code sun.awt.windows.WToolkit}.
- *
- *
- * On platforms without a GUI, this value is {@code null}.
- *
- *
- * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
- * not exist.
- *
- *
- * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
- * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
- * sync with that System property.
- *
- *
- * @since 2.1
- */
- public static final String AWT_TOOLKIT = getSystemProperty("awt.toolkit");
-
- /**
- *
- * The {@code file.encoding} System Property.
- *
- *
- * File encoding, such as {@code Cp1252}.
- *
- *
- * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
- * not exist.
- *
- *
- * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
- * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
- * sync with that System property.
- *
- *
- * @since 2.0
- * @since Java 1.2
- */
- public static final String FILE_ENCODING = getSystemProperty("file.encoding");
-
- /**
- *
- * The {@code file.separator} System Property. File separator ("/" on UNIX).
- *
- *
- * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
- * not exist.
- *
- *
- * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
- * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
- * sync with that System property.
- *
- *
- * @since Java 1.1
- */
- public static final String FILE_SEPARATOR = getSystemProperty("file.separator");
-
- /**
- *
- * The {@code java.awt.fonts} System Property.
- *
- *
- * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
- * not exist.
- *
- *
- * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
- * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
- * sync with that System property.
- *
- *
- * @since 2.1
- */
- public static final String JAVA_AWT_FONTS = getSystemProperty("java.awt.fonts");
-
- /**
- *
- * The {@code java.awt.graphicsenv} System Property.
- *
- *
- * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
- * not exist.
- *
- *
- * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
- * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
- * sync with that System property.
- *
- *
- * @since 2.1
- */
- public static final String JAVA_AWT_GRAPHICSENV = getSystemProperty("java.awt.graphicsenv");
-
- /**
- *
- * The {@code java.awt.headless} System Property. The value of this property is the String {@code "true"} or
- * {@code "false"}.
- *
- *
- * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
- * not exist.
- *
- *
- * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
- * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
- * sync with that System property.
- *
- *
- * @see #isJavaAwtHeadless()
- * @since 2.1
- * @since Java 1.4
- */
- public static final String JAVA_AWT_HEADLESS = getSystemProperty("java.awt.headless");
-
- /**
- *
- * The {@code java.awt.printerjob} System Property.
- *
- *
- * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
- * not exist.
- *
- *
- * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
- * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
- * sync with that System property.
- *
- *
- * @since 2.1
- */
- public static final String JAVA_AWT_PRINTERJOB = getSystemProperty("java.awt.printerjob");
-
- /**
- *
- * The {@code java.class.path} System Property. Java class path.
- *
- *
- * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
- * not exist.
- *
- *
- * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
- * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
- * sync with that System property.
- *
- *
- * @since Java 1.1
- */
- public static final String JAVA_CLASS_PATH = getSystemProperty("java.class.path");
-
- /**
- *
- * The {@code java.class.version} System Property. Java class format version number.
- *
- *
- * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
- * not exist.
- *
- *
- * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
- * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
- * sync with that System property.
- *
- *
- * @since Java 1.1
- */
- public static final String JAVA_CLASS_VERSION = getSystemProperty("java.class.version");
-
- /**
- *
- * The {@code java.compiler} System Property. Name of JIT compiler to use. First in JDK version 1.2. Not used in Sun
- * JDKs after 1.2.
- *
- *
- * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
- * not exist.
- *
- *
- * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
- * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
- * sync with that System property.
- *
- *
- * @since Java 1.2. Not used in Sun versions after 1.2.
- */
- public static final String JAVA_COMPILER = getSystemProperty("java.compiler");
-
- /**
- *
- * The {@code java.endorsed.dirs} System Property. Path of endorsed directory or directories.
- *
- *
- * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
- * not exist.
- *
- *
- * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
- * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
- * sync with that System property.
- *
- *
- * @since Java 1.4
- */
- public static final String JAVA_ENDORSED_DIRS = getSystemProperty("java.endorsed.dirs");
-
- /**
- *
- * The {@code java.ext.dirs} System Property. Path of extension directory or directories.
- *
- *
- * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
- * not exist.
- *
- *
- * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
- * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
- * sync with that System property.
- *
- *
- * @since Java 1.3
- */
- public static final String JAVA_EXT_DIRS = getSystemProperty("java.ext.dirs");
-
- /**
- *
- * The {@code java.home} System Property. Java installation directory.
- *
- *
- * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
- * not exist.
- *
- *
- * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
- * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
- * sync with that System property.
- *
- *
- * @since Java 1.1
- */
- public static final String JAVA_HOME = getSystemProperty(JAVA_HOME_KEY);
-
- /**
- *
- * The {@code java.io.tmpdir} System Property. Default temp file path.
- *
- *
- * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
- * not exist.
- *
- *
- * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
- * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
- * sync with that System property.
- *
- *
- * @since Java 1.2
- */
- public static final String JAVA_IO_TMPDIR = getSystemProperty(JAVA_IO_TMPDIR_KEY);
-
- /**
- *
- * The {@code java.library.path} System Property. List of paths to search when loading libraries.
- *
- *
- * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
- * not exist.
- *
- *
- * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
- * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
- * sync with that System property.
- *
- *
- * @since Java 1.2
- */
- public static final String JAVA_LIBRARY_PATH = getSystemProperty("java.library.path");
-
- /**
- *
- * The {@code java.runtime.name} System Property. Java Runtime Environment name.
- *
- *
- * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
- * not exist.
- *
- *
- * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
- * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
- * sync with that System property.
- *
- *
- * @since 2.0
- * @since Java 1.3
- */
- public static final String JAVA_RUNTIME_NAME = getSystemProperty("java.runtime.name");
-
- /**
- *
- * The {@code java.runtime.version} System Property. Java Runtime Environment version.
- *
- *
- * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
- * not exist.
- *
- *
- * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
- * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
- * sync with that System property.
- *
- *
- * @since 2.0
- * @since Java 1.3
- */
- public static final String JAVA_RUNTIME_VERSION = getSystemProperty("java.runtime.version");
-
- /**
- *
- * The {@code java.specification.name} System Property. Java Runtime Environment specification name.
- *
- *
- * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
- * not exist.
- *
- *
- * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
- * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
- * sync with that System property.
- *
- *
- * @since Java 1.2
- */
- public static final String JAVA_SPECIFICATION_NAME = getSystemProperty("java.specification.name");
-
- /**
- *
- * The {@code java.specification.vendor} System Property. Java Runtime Environment specification vendor.
- *
- *
- * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
- * not exist.
- *
- *
- * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
- * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
- * sync with that System property.
- *
- *
- * @since Java 1.2
- */
- public static final String JAVA_SPECIFICATION_VENDOR = getSystemProperty("java.specification.vendor");
-
- /**
- *
- * The {@code java.specification.version} System Property. Java Runtime Environment specification version.
- *
- *
- * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
- * not exist.
- *
- *
- * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
- * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
- * sync with that System property.
- *
- *
- * @since Java 1.3
- */
- public static final String JAVA_SPECIFICATION_VERSION = getSystemProperty("java.specification.version");
- private static final JavaVersion JAVA_SPECIFICATION_VERSION_AS_ENUM = JavaVersion.get(JAVA_SPECIFICATION_VERSION);
-
- /**
- *
- * The {@code java.util.prefs.PreferencesFactory} System Property. A class name.
- *
- *
- * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
- * not exist.
- *
- *
- * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
- * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
- * sync with that System property.
- *
- *
- * @since 2.1
- * @since Java 1.4
- */
- public static final String JAVA_UTIL_PREFS_PREFERENCES_FACTORY =
- getSystemProperty("java.util.prefs.PreferencesFactory");
-
- /**
- *
- * The {@code java.vendor} System Property. Java vendor-specific string.
- *
- *
- * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
- * not exist.
- *
- *
- * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
- * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
- * sync with that System property.
- *
- *
- * @since Java 1.1
- */
- public static final String JAVA_VENDOR = getSystemProperty("java.vendor");
-
- /**
- *
- * The {@code java.vendor.url} System Property. Java vendor URL.
- *
- *
- * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
- * not exist.
- *
- *
- * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
- * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
- * sync with that System property.
- *
- *
- * @since Java 1.1
- */
- public static final String JAVA_VENDOR_URL = getSystemProperty("java.vendor.url");
-
- /**
- *
- * The {@code java.version} System Property. Java version number.
- *
- *
- * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
- * not exist.
- *
- *
- * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
- * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
- * sync with that System property.
- *
- *
- * @since Java 1.1
- */
- public static final String JAVA_VERSION = getSystemProperty("java.version");
-
- /**
- *
- * The {@code java.vm.info} System Property. Java Virtual Machine implementation info.
- *
- *
- * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
- * not exist.
- *
- *
- * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
- * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
- * sync with that System property.
- *
- *
- * @since 2.0
- * @since Java 1.2
- */
- public static final String JAVA_VM_INFO = getSystemProperty("java.vm.info");
-
- /**
- *
- * The {@code java.vm.name} System Property. Java Virtual Machine implementation name.
- *
- *
- * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
- * not exist.
- *
- *
- * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
- * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
- * sync with that System property.
- *
- *
- * @since Java 1.2
- */
- public static final String JAVA_VM_NAME = getSystemProperty("java.vm.name");
-
- /**
- *
- * The {@code java.vm.specification.name} System Property. Java Virtual Machine specification name.
- *
- *
- * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
- * not exist.
- *
- *
- * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
- * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
- * sync with that System property.
- *
- *
- * @since Java 1.2
- */
- public static final String JAVA_VM_SPECIFICATION_NAME = getSystemProperty("java.vm.specification.name");
-
- /**
- *
- * The {@code java.vm.specification.vendor} System Property. Java Virtual Machine specification vendor.
- *
- *
- * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
- * not exist.
- *
- *
- * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
- * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
- * sync with that System property.
- *
- *
- * @since Java 1.2
- */
- public static final String JAVA_VM_SPECIFICATION_VENDOR = getSystemProperty("java.vm.specification.vendor");
-
- /**
- *
- * The {@code java.vm.specification.version} System Property. Java Virtual Machine specification version.
- *
- *
- * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
- * not exist.
- *
- *
- * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
- * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
- * sync with that System property.
- *
- *
- * @since Java 1.2
- */
- public static final String JAVA_VM_SPECIFICATION_VERSION = getSystemProperty("java.vm.specification.version");
-
- /**
- *
- * The {@code java.vm.vendor} System Property. Java Virtual Machine implementation vendor.
- *
- *
- * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
- * not exist.
- *
- *
- * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
- * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
- * sync with that System property.
- *
- *
- * @since Java 1.2
- */
- public static final String JAVA_VM_VENDOR = getSystemProperty("java.vm.vendor");
-
- /**
- *
- * The {@code java.vm.version} System Property. Java Virtual Machine implementation version.
- *
- *
- * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
- * not exist.
- *
- *
- * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
- * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
- * sync with that System property.
- *
- *
- * @since Java 1.2
- */
- public static final String JAVA_VM_VERSION = getSystemProperty("java.vm.version");
-
- /**
- *
- * The {@code line.separator} System Property. Line separator ("\n" on UNIX).
- *
- *
- * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
- * not exist.
- *
- *
- * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
- * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
- * sync with that System property.
- *
- *
- * @since Java 1.1
- */
- public static final String LINE_SEPARATOR = getSystemProperty("line.separator");
-
- /**
- *
- * The {@code os.arch} System Property. Operating system architecture.
- *
- *
- * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
- * not exist.
- *
- *
- * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
- * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
- * sync with that System property.
- *
- *
- * @since Java 1.1
- */
- public static final String OS_ARCH = getSystemProperty("os.arch");
-
- /**
- *
- * The {@code os.name} System Property. Operating system name.
- *
- *
- * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
- * not exist.
- *
- *
- * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
- * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
- * sync with that System property.
- *
- *
- * @since Java 1.1
- */
- public static final String OS_NAME = getSystemProperty("os.name");
-
- /**
- *
- * The {@code os.version} System Property. Operating system version.
- *
- *
- * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
- * not exist.
- *
- *
- * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
- * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
- * sync with that System property.
- *
- *
- * @since Java 1.1
- */
- public static final String OS_VERSION = getSystemProperty("os.version");
-
- /**
- *
- * The {@code path.separator} System Property. Path separator (":" on UNIX).
- *
- *
- * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
- * not exist.
- *
- *
- * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
- * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
- * sync with that System property.
- *
- *
- * @since Java 1.1
- */
- public static final String PATH_SEPARATOR = getSystemProperty("path.separator");
-
- /**
- *
- * The {@code user.country} or {@code user.region} System Property. User's country code, such as {@code GB}. First
- * in Java version 1.2 as {@code user.region}. Renamed to {@code user.country} in 1.4
- *
- *
- * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
- * not exist.
- *
- *
- * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
- * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
- * sync with that System property.
- *
- *
- * @since 2.0
- * @since Java 1.2
- */
- public static final String USER_COUNTRY = getSystemProperty("user.country") == null ?
- getSystemProperty("user.region") : getSystemProperty("user.country");
-
- /**
- *
- * The {@code user.dir} System Property. User's current working directory.
- *
- *
- * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
- * not exist.
- *
- *
- * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
- * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
- * sync with that System property.
- *
- *
- * @since Java 1.1
- */
- public static final String USER_DIR = getSystemProperty(USER_DIR_KEY);
-
- /**
- *
- * The {@code user.home} System Property. User's home directory.
- *
- *
- * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
- * not exist.
- *
- *
- * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
- * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
- * sync with that System property.
- *
- *
- * @since Java 1.1
- */
- public static final String USER_HOME = getSystemProperty(USER_HOME_KEY);
-
- /**
- *
- * The {@code user.language} System Property. User's language code, such as {@code "en"}.
- *
- *
- * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
- * not exist.
- *
- *
- * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
- * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
- * sync with that System property.
- *
- *
- * @since 2.0
- * @since Java 1.2
- */
- public static final String USER_LANGUAGE = getSystemProperty("user.language");
-
- /**
- *
- * The {@code user.name} System Property. User's account name.
- *
- *
- * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
- * not exist.
- *
- *
- * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
- * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
- * sync with that System property.
- *
- *
- * @since Java 1.1
- */
- public static final String USER_NAME = getSystemProperty("user.name");
-
- /**
- *
- * The {@code user.timezone} System Property. For example: {@code "America/Los_Angeles"}.
- *
- *
- * Defaults to {@code null} if the runtime does not have security access to read this property or the property does
- * not exist.
- *
- *
- * This value is initialized when the class is loaded. If {@link System#setProperty(String,String)} or
- * {@link System#setProperties(java.util.Properties)} is called after this class is loaded, the value will be out of
- * sync with that System property.
- *
- *
- * @since 2.1
- */
- public static final String USER_TIMEZONE = getSystemProperty("user.timezone");
-
- // Java version checks
- // -----------------------------------------------------------------------
- // These MUST be declared after those above as they depend on the
- // values being set up
-
- /**
- *
- * Is {@code true} if this is Java version 1.1 (also 1.1.x versions).
- *
- *
- * The field will return {@code false} if {@link #JAVA_VERSION} is {@code null}.
- *
- */
- public static final boolean IS_JAVA_1_1 = getJavaVersionMatches("1.1");
-
- /**
- *
- * Is {@code true} if this is Java version 1.2 (also 1.2.x versions).
- *
- *
- * The field will return {@code false} if {@link #JAVA_VERSION} is {@code null}.
- *
- */
- public static final boolean IS_JAVA_1_2 = getJavaVersionMatches("1.2");
-
- /**
- *
- * Is {@code true} if this is Java version 1.3 (also 1.3.x versions).
- *
- *
- * The field will return {@code false} if {@link #JAVA_VERSION} is {@code null}.
- *
- */
- public static final boolean IS_JAVA_1_3 = getJavaVersionMatches("1.3");
-
- /**
- *
- * Is {@code true} if this is Java version 1.4 (also 1.4.x versions).
- *
- *
- * The field will return {@code false} if {@link #JAVA_VERSION} is {@code null}.
- *
- */
- public static final boolean IS_JAVA_1_4 = getJavaVersionMatches("1.4");
-
- /**
- *
- * Is {@code true} if this is Java version 1.5 (also 1.5.x versions).
- *
- *
- * The field will return {@code false} if {@link #JAVA_VERSION} is {@code null}.
- *
- */
- public static final boolean IS_JAVA_1_5 = getJavaVersionMatches("1.5");
-
- /**
- *
- * Is {@code true} if this is Java version 1.6 (also 1.6.x versions).
- *
- *
- * The field will return {@code false} if {@link #JAVA_VERSION} is {@code null}.
- *
- */
- public static final boolean IS_JAVA_1_6 = getJavaVersionMatches("1.6");
-
- /**
- *
- * Is {@code true} if this is Java version 1.7 (also 1.7.x versions).
- *
- *
- * The field will return {@code false} if {@link #JAVA_VERSION} is {@code null}.
- *
- *
- * @since 3.0
- */
- public static final boolean IS_JAVA_1_7 = getJavaVersionMatches("1.7");
-
- // Operating system checks
- // -----------------------------------------------------------------------
- // These MUST be declared after those above as they depend on the
- // values being set up
- // OS names from http://www.vamphq.com/os.html
- // Selected ones included - please advise dev@commons.apache.org
- // if you want another added or a mistake corrected
-
- /**
- *
- * Is {@code true} if this is AIX.
- *
- *
- * The field will return {@code false} if {@code OS_NAME} is {@code null}.
- *
- *
- * @since 2.0
- */
- public static final boolean IS_OS_AIX = getOSMatchesName("AIX");
-
- /**
- *
- * Is {@code true} if this is HP-UX.
- *
- *
- * The field will return {@code false} if {@code OS_NAME} is {@code null}.
- *
- *
- * @since 2.0
- */
- public static final boolean IS_OS_HP_UX = getOSMatchesName("HP-UX");
-
- /**
- *
- * Is {@code true} if this is Irix.
- *
- *
- * The field will return {@code false} if {@code OS_NAME} is {@code null}.
- *
- *
- * @since 2.0
- */
- public static final boolean IS_OS_IRIX = getOSMatchesName("Irix");
-
- /**
- *
- * Is {@code true} if this is Linux.
- *
- *
- * The field will return {@code false} if {@code OS_NAME} is {@code null}.
- *
- *
- * @since 2.0
- */
- public static final boolean IS_OS_LINUX = getOSMatchesName("Linux") || getOSMatchesName("LINUX");
-
- /**
- *
- * Is {@code true} if this is Mac.
- *
- *
- * The field will return {@code false} if {@code OS_NAME} is {@code null}.
- *
- *
- * @since 2.0
- */
- public static final boolean IS_OS_MAC = getOSMatchesName("Mac");
-
- /**
- *
- * Is {@code true} if this is Mac.
- *
- *
- * The field will return {@code false} if {@code OS_NAME} is {@code null}.
- *
- *
- * @since 2.0
- */
- public static final boolean IS_OS_MAC_OSX = getOSMatchesName("Mac OS X");
-
- /**
- *
- * Is {@code true} if this is FreeBSD.
- *
- *
- * The field will return {@code false} if {@code OS_NAME} is {@code null}.
- *
- *
- * @since 3.1
- */
- public static final boolean IS_OS_FREE_BSD = getOSMatchesName("FreeBSD");
-
- /**
- *
- * Is {@code true} if this is OpenBSD.
- *
- *
- * The field will return {@code false} if {@code OS_NAME} is {@code null}.
- *
- *
- * @since 3.1
- */
- public static final boolean IS_OS_OPEN_BSD = getOSMatchesName("OpenBSD");
-
- /**
- *
- * Is {@code true} if this is NetBSD.
- *
- *
- * The field will return {@code false} if {@code OS_NAME} is {@code null}.
- *
- *
- * @since 3.1
- */
- public static final boolean IS_OS_NET_BSD = getOSMatchesName("NetBSD");
-
- /**
- *
- * Is {@code true} if this is OS/2.
- *
- *
- * The field will return {@code false} if {@code OS_NAME} is {@code null}.
- *
- *
- * @since 2.0
- */
- public static final boolean IS_OS_OS2 = getOSMatchesName("OS/2");
-
- /**
- *
- * Is {@code true} if this is Solaris.
- *
- *
- * The field will return {@code false} if {@code OS_NAME} is {@code null}.
- *
- *
- * @since 2.0
- */
- public static final boolean IS_OS_SOLARIS = getOSMatchesName("Solaris");
-
- /**
- *
- * Is {@code true} if this is SunOS.
- *
- *
- * The field will return {@code false} if {@code OS_NAME} is {@code null}.
- *
- *
- * @since 2.0
- */
- public static final boolean IS_OS_SUN_OS = getOSMatchesName("SunOS");
-
- /**
- *
- * Is {@code true} if this is a UNIX like system, as in any of AIX, HP-UX, Irix, Linux, MacOSX, Solaris or SUN OS.
- *
- *
- * The field will return {@code false} if {@code OS_NAME} is {@code null}.
- *
- *
- * @since 2.1
- */
- public static final boolean IS_OS_UNIX = IS_OS_AIX || IS_OS_HP_UX || IS_OS_IRIX || IS_OS_LINUX || IS_OS_MAC_OSX
- || IS_OS_SOLARIS || IS_OS_SUN_OS || IS_OS_FREE_BSD || IS_OS_OPEN_BSD || IS_OS_NET_BSD;
-
- /**
- *
- * Is {@code true} if this is Windows.
- *
- *
- * The field will return {@code false} if {@code OS_NAME} is {@code null}.
- *
- *
- * @since 2.0
- */
- public static final boolean IS_OS_WINDOWS = getOSMatchesName(OS_NAME_WINDOWS_PREFIX);
-
- /**
- *
- * Is {@code true} if this is Windows 2000.
- *
- *
- * The field will return {@code false} if {@code OS_NAME} is {@code null}.
- *
- *
- * @since 2.0
- */
- public static final boolean IS_OS_WINDOWS_2000 = getOSMatches(OS_NAME_WINDOWS_PREFIX, "5.0");
-
- /**
- *
- * Is {@code true} if this is Windows 2003.
- *
- *
- * The field will return {@code false} if {@code OS_NAME} is {@code null}.
- *
- *
- * @since 3.1
- */
- public static final boolean IS_OS_WINDOWS_2003 = getOSMatches(OS_NAME_WINDOWS_PREFIX, "5.2");
-
- /**
- *
- * Is {@code true} if this is Windows 2008.
- *
- *
- * The field will return {@code false} if {@code OS_NAME} is {@code null}.
- *
- *
- * @since 3.1
- */
- public static final boolean IS_OS_WINDOWS_2008 = getOSMatches(OS_NAME_WINDOWS_PREFIX + " Server 2008", "6.1");
-
- /**
- *
- * Is {@code true} if this is Windows 95.
- *
- *
- * The field will return {@code false} if {@code OS_NAME} is {@code null}.
- *
- *
- * @since 2.0
- */
- public static final boolean IS_OS_WINDOWS_95 = getOSMatches(OS_NAME_WINDOWS_PREFIX + " 9", "4.0");
- // Java 1.2 running on Windows98 returns 'Windows 95', hence the above
-
- /**
- *
- * Is {@code true} if this is Windows 98.
- *
- *
- * The field will return {@code false} if {@code OS_NAME} is {@code null}.
- *
- *
- * @since 2.0
- */
- public static final boolean IS_OS_WINDOWS_98 = getOSMatches(OS_NAME_WINDOWS_PREFIX + " 9", "4.1");
- // Java 1.2 running on Windows98 returns 'Windows 95', hence the above
-
- /**
- *
- * Is {@code true} if this is Windows ME.
- *
- *
- * The field will return {@code false} if {@code OS_NAME} is {@code null}.
- *
- *
- * @since 2.0
- */
- public static final boolean IS_OS_WINDOWS_ME = getOSMatches(OS_NAME_WINDOWS_PREFIX, "4.9");
- // Java 1.2 running on WindowsME may return 'Windows 95', hence the above
-
- /**
- *
- * Is {@code true} if this is Windows NT.
- *
- *
- * The field will return {@code false} if {@code OS_NAME} is {@code null}.
- *
- *
- * @since 2.0
- */
- public static final boolean IS_OS_WINDOWS_NT = getOSMatchesName(OS_NAME_WINDOWS_PREFIX + " NT");
- // Windows 2000 returns 'Windows 2000' but may suffer from same Java1.2 problem
-
- /**
- *
- * Is {@code true} if this is Windows XP.
- *
- *
- * The field will return {@code false} if {@code OS_NAME} is {@code null}.
- *
- *
- * @since 2.0
- */
- public static final boolean IS_OS_WINDOWS_XP = getOSMatches(OS_NAME_WINDOWS_PREFIX, "5.1");
-
- // -----------------------------------------------------------------------
- /**
- *
- * Is {@code true} if this is Windows Vista.
- *
- *
- * The field will return {@code false} if {@code OS_NAME} is {@code null}.
- *
- *
- * @since 2.4
- */
- public static final boolean IS_OS_WINDOWS_VISTA = getOSMatches(OS_NAME_WINDOWS_PREFIX, "6.0");
-
- /**
- *
- * Is {@code true} if this is Windows 7.
- *
- *
- * The field will return {@code false} if {@code OS_NAME} is {@code null}.
- *
- *
- * @since 3.0
- */
- public static final boolean IS_OS_WINDOWS_7 = getOSMatches(OS_NAME_WINDOWS_PREFIX, "6.1");
-
- /**
- *
- * Gets the Java home directory as a {@code File}.
- *
- *
- * @return a directory
- * @throws SecurityException if a security manager exists and its {@code checkPropertyAccess} method doesn't allow
- * access to the specified system property.
- * @see System#getProperty(String)
- * @since 2.1
- */
- public static File getJavaHome() {
- return new File(System.getProperty(JAVA_HOME_KEY));
- }
-
- /**
- *
- * Gets the Java IO temporary directory as a {@code File}.
- *
- *
- * @return a directory
- * @throws SecurityException if a security manager exists and its {@code checkPropertyAccess} method doesn't allow
- * access to the specified system property.
- * @see System#getProperty(String)
- * @since 2.1
- */
- public static File getJavaIoTmpDir() {
- return new File(System.getProperty(JAVA_IO_TMPDIR_KEY));
- }
-
- /**
- *
- * Decides if the Java version matches.
- *
- *
- * @param versionPrefix the prefix for the java version
- * @return true if matches, or false if not or can't determine
- */
- private static boolean getJavaVersionMatches(String versionPrefix) {
- return isJavaVersionMatch(JAVA_SPECIFICATION_VERSION, versionPrefix);
- }
-
- /**
- * Decides if the operating system matches.
- *
- * @param osNamePrefix the prefix for the os name
- * @param osVersionPrefix the prefix for the version
- * @return true if matches, or false if not or can't determine
- */
- private static boolean getOSMatches(String osNamePrefix, String osVersionPrefix) {
- return isOSMatch(OS_NAME, OS_VERSION, osNamePrefix, osVersionPrefix);
- }
-
- /**
- * Decides if the operating system matches.
- *
- * @param osNamePrefix the prefix for the os name
- * @return true if matches, or false if not or can't determine
- */
- private static boolean getOSMatchesName(String osNamePrefix) {
- return isOSNameMatch(OS_NAME, osNamePrefix);
- }
-
- // -----------------------------------------------------------------------
- /**
- *
- * Gets a System property, defaulting to {@code null} if the property cannot be read.
- *
- *
- * If a {@code SecurityException} is caught, the return value is {@code null} and a message is written to
- * {@code System.err}.
- *
- *
- * @param property the system property name
- * @return the system property value or {@code null} if a security problem occurs
- */
- private static String getSystemProperty(String property) {
- try {
- return System.getProperty(property);
- } catch (SecurityException ex) {
- // we are not allowed to look at this property
- System.err.println("Caught a SecurityException reading the system property '" + property
- + "'; the SystemUtils property value will default to null.");
- return null;
- }
- }
-
- /**
- *
- * Gets the user directory as a {@code File}.
- *
- *
- * @return a directory
- * @throws SecurityException if a security manager exists and its {@code checkPropertyAccess} method doesn't allow
- * access to the specified system property.
- * @see System#getProperty(String)
- * @since 2.1
- */
- public static File getUserDir() {
- return new File(System.getProperty(USER_DIR_KEY));
- }
-
- /**
- *
- * Gets the user home directory as a {@code File}.
- *
- *
- * @return a directory
- * @throws SecurityException if a security manager exists and its {@code checkPropertyAccess} method doesn't allow
- * access to the specified system property.
- * @see System#getProperty(String)
- * @since 2.1
- */
- public static File getUserHome() {
- return new File(System.getProperty(USER_HOME_KEY));
- }
-
- /**
- * Returns whether the {@link #JAVA_AWT_HEADLESS} value is {@code true}.
- *
- * @return {@code true} if {@code JAVA_AWT_HEADLESS} is {@code "true"}, {@code false} otherwise.
- * @see #JAVA_AWT_HEADLESS
- * @since 2.1
- * @since Java 1.4
- */
- public static boolean isJavaAwtHeadless() {
- return JAVA_AWT_HEADLESS != null ? JAVA_AWT_HEADLESS.equals(Boolean.TRUE.toString()) : false;
- }
-
- /**
- *
- * Is the Java version at least the requested version.
- *
- *
- * Example input:
- *
- *
- * {@code 1.2f} to test for Java 1.2
- * {@code 1.31f} to test for Java 1.3.1
- *
- *
- * @param requiredVersion the required version, for example 1.31f
- * @return {@code true} if the actual version is equal or greater than the required version
- */
- public static boolean isJavaVersionAtLeast(JavaVersion requiredVersion) {
- return JAVA_SPECIFICATION_VERSION_AS_ENUM.atLeast(requiredVersion);
- }
-
- /**
- *
- * Decides if the Java version matches.
- *
- *
- * This method is package private instead of private to support unit test invocation.
- *
- *
- * @param version the actual Java version
- * @param versionPrefix the prefix for the expected Java version
- * @return true if matches, or false if not or can't determine
- */
- static boolean isJavaVersionMatch(String version, String versionPrefix) {
- if (version == null) {
- return false;
- }
- return version.startsWith(versionPrefix);
- }
-
- /**
- * Decides if the operating system matches.
- *
- * This method is package private instead of private to support unit test invocation.
- *
- *
- * @param osName the actual OS name
- * @param osVersion the actual OS version
- * @param osNamePrefix the prefix for the expected OS name
- * @param osVersionPrefix the prefix for the expected OS version
- * @return true if matches, or false if not or can't determine
- */
- static boolean isOSMatch(String osName, String osVersion, String osNamePrefix, String osVersionPrefix) {
- if (osName == null || osVersion == null) {
- return false;
- }
- return osName.startsWith(osNamePrefix) && osVersion.startsWith(osVersionPrefix);
- }
-
- /**
- * Decides if the operating system matches.
- *
- * This method is package private instead of private to support unit test invocation.
- *
- *
- * @param osName the actual OS name
- * @param osNamePrefix the prefix for the expected OS name
- * @return true if matches, or false if not or can't determine
- */
- static boolean isOSNameMatch(String osName, String osNamePrefix) {
- if (osName == null) {
- return false;
- }
- return osName.startsWith(osNamePrefix);
- }
-
- // -----------------------------------------------------------------------
- /**
- *
- * SystemUtils instances should NOT be constructed in standard programming. Instead, the class should be used as
- * {@code SystemUtils.FILE_SEPARATOR}.
- *
- *
- * This constructor is public to permit tools that require a JavaBean instance to operate.
- *
- */
- public SystemUtils() {
- super();
- }
-
-}
diff --git a/core/src/main/java/external/org/apache/commons/lang3/Validate.java b/core/src/main/java/external/org/apache/commons/lang3/Validate.java
deleted file mode 100644
index 72213854..00000000
--- a/core/src/main/java/external/org/apache/commons/lang3/Validate.java
+++ /dev/null
@@ -1,1070 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package external.org.apache.commons.lang3;
-
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.regex.Pattern;
-
-/**
- * This class assists in validating arguments. The validation methods are
- * based along the following principles:
- *
- * An invalid {@code null} argument causes a {@link NullPointerException}.
- * A non-{@code null} argument causes an {@link IllegalArgumentException}.
- * An invalid index into an array/collection/map/string causes an {@link IndexOutOfBoundsException}.
- *
- *
- * All exceptions messages are
- * format strings
- * as defined by the Java platform. For example:
- *
- *
- * Validate.isTrue(i > 0, "The value must be greater than zero: %d", i);
- * Validate.notNull(surname, "The surname must not be %s", null);
- *
- *
- * #ThreadSafe#
- * @version $Id: Validate.java 1199983 2011-11-09 21:41:24Z ggregory $
- * @see java.lang.String#format(String, Object...)
- * @since 2.0
- */
-public class Validate {
-
- private static final String DEFAULT_EXCLUSIVE_BETWEEN_EX_MESSAGE =
- "The value %s is not in the specified exclusive range of %s to %s";
- private static final String DEFAULT_INCLUSIVE_BETWEEN_EX_MESSAGE =
- "The value %s is not in the specified inclusive range of %s to %s";
- private static final String DEFAULT_MATCHES_PATTERN_EX = "The string %s does not match the pattern %s";
- private static final String DEFAULT_IS_NULL_EX_MESSAGE = "The validated object is null";
- private static final String DEFAULT_IS_TRUE_EX_MESSAGE = "The validated expression is false";
- private static final String DEFAULT_NO_NULL_ELEMENTS_ARRAY_EX_MESSAGE =
- "The validated array contains null element at index: %d";
- private static final String DEFAULT_NO_NULL_ELEMENTS_COLLECTION_EX_MESSAGE =
- "The validated collection contains null element at index: %d";
- private static final String DEFAULT_NOT_BLANK_EX_MESSAGE = "The validated character sequence is blank";
- private static final String DEFAULT_NOT_EMPTY_ARRAY_EX_MESSAGE = "The validated array is empty";
- private static final String DEFAULT_NOT_EMPTY_CHAR_SEQUENCE_EX_MESSAGE =
- "The validated character sequence is empty";
- private static final String DEFAULT_NOT_EMPTY_COLLECTION_EX_MESSAGE = "The validated collection is empty";
- private static final String DEFAULT_NOT_EMPTY_MAP_EX_MESSAGE = "The validated map is empty";
- private static final String DEFAULT_VALID_INDEX_ARRAY_EX_MESSAGE = "The validated array index is invalid: %d";
- private static final String DEFAULT_VALID_INDEX_CHAR_SEQUENCE_EX_MESSAGE =
- "The validated character sequence index is invalid: %d";
- private static final String DEFAULT_VALID_INDEX_COLLECTION_EX_MESSAGE =
- "The validated collection index is invalid: %d";
- private static final String DEFAULT_VALID_STATE_EX_MESSAGE = "The validated state is false";
- private static final String DEFAULT_IS_ASSIGNABLE_EX_MESSAGE = "Cannot assign a %s to a %s";
- private static final String DEFAULT_IS_INSTANCE_OF_EX_MESSAGE = "Expected type: %s, actual: %s";
-
- /**
- * Constructor. This class should not normally be instantiated.
- */
- public Validate() {
- super();
- }
-
- // isTrue
- //---------------------------------------------------------------------------------
-
- /**
- * Validate that the argument condition is {@code true}; otherwise
- * throwing an exception with the specified message. This method is useful when
- * validating according to an arbitrary boolean expression, such as validating a
- * primitive number or using your own custom validation expression.
- *
- * Validate.isTrue(i > 0.0, "The value must be greater than zero: %d", i);
- *
- * For performance reasons, the long value is passed as a separate parameter and
- * appended to the exception message only in the case of an error.
- *
- * @param expression the boolean expression to check
- * @param message the {@link String#format(String, Object...)} exception message if invalid, not null
- * @param value the value to append to the message when invalid
- * @throws IllegalArgumentException if expression is {@code false}
- * @see #isTrue(boolean)
- * @see #isTrue(boolean, String, double)
- * @see #isTrue(boolean, String, Object...)
- */
- public static void isTrue(boolean expression, String message, long value) {
- if (expression == false) {
- throw new IllegalArgumentException(String.format(message, Long.valueOf(value)));
- }
- }
-
- /**
- * Validate that the argument condition is {@code true}; otherwise
- * throwing an exception with the specified message. This method is useful when
- * validating according to an arbitrary boolean expression, such as validating a
- * primitive number or using your own custom validation expression.
- *
- * Validate.isTrue(d > 0.0, "The value must be greater than zero: %s", d);
- *
- * For performance reasons, the double value is passed as a separate parameter and
- * appended to the exception message only in the case of an error.
- *
- * @param expression the boolean expression to check
- * @param message the {@link String#format(String, Object...)} exception message if invalid, not null
- * @param value the value to append to the message when invalid
- * @throws IllegalArgumentException if expression is {@code false}
- * @see #isTrue(boolean)
- * @see #isTrue(boolean, String, long)
- * @see #isTrue(boolean, String, Object...)
- */
- public static void isTrue(boolean expression, String message, double value) {
- if (expression == false) {
- throw new IllegalArgumentException(String.format(message, Double.valueOf(value)));
- }
- }
-
- /**
- * Validate that the argument condition is {@code true}; otherwise
- * throwing an exception with the specified message. This method is useful when
- * validating according to an arbitrary boolean expression, such as validating a
- * primitive number or using your own custom validation expression.
- *
- *
- * Validate.isTrue(i >= min && i <= max, "The value must be between %d and %d", min, max);
- * Validate.isTrue(myObject.isOk(), "The object is not okay");
- *
- * @param expression the boolean expression to check
- * @param message the {@link String#format(String, Object...)} exception message if invalid, not null
- * @param values the optional values for the formatted exception message, null array not recommended
- * @throws IllegalArgumentException if expression is {@code false}
- * @see #isTrue(boolean)
- * @see #isTrue(boolean, String, long)
- * @see #isTrue(boolean, String, double)
- */
- public static void isTrue(boolean expression, String message, Object... values) {
- if (expression == false) {
- throw new IllegalArgumentException(String.format(message, values));
- }
- }
-
- /**
- * Validate that the argument condition is {@code true}; otherwise
- * throwing an exception. This method is useful when validating according
- * to an arbitrary boolean expression, such as validating a
- * primitive number or using your own custom validation expression.
- *
- *
- * Validate.isTrue(i > 0);
- * Validate.isTrue(myObject.isOk());
- *
- * The message of the exception is "The validated expression is
- * false".
- *
- * @param expression the boolean expression to check
- * @throws IllegalArgumentException if expression is {@code false}
- * @see #isTrue(boolean, String, long)
- * @see #isTrue(boolean, String, double)
- * @see #isTrue(boolean, String, Object...)
- */
- public static void isTrue(boolean expression) {
- if (expression == false) {
- throw new IllegalArgumentException(DEFAULT_IS_TRUE_EX_MESSAGE);
- }
- }
-
- // notNull
- //---------------------------------------------------------------------------------
-
- /**
- * Validate that the specified argument is not {@code null};
- * otherwise throwing an exception.
- *
- *
Validate.notNull(myObject, "The object must not be null");
- *
- * The message of the exception is "The validated object is
- * null".
- *
- * @param the object type
- * @param object the object to check
- * @return the validated object (never {@code null} for method chaining)
- * @throws NullPointerException if the object is {@code null}
- * @see #notNull(Object, String, Object...)
- */
- public static T notNull(T object) {
- return notNull(object, DEFAULT_IS_NULL_EX_MESSAGE);
- }
-
- /**
- * Validate that the specified argument is not {@code null};
- * otherwise throwing an exception with the specified message.
- *
- *
Validate.notNull(myObject, "The object must not be null");
- *
- * @param the object type
- * @param object the object to check
- * @param message the {@link String#format(String, Object...)} exception message if invalid, not null
- * @param values the optional values for the formatted exception message
- * @return the validated object (never {@code null} for method chaining)
- * @throws NullPointerException if the object is {@code null}
- * @see #notNull(Object)
- */
- public static T notNull(T object, String message, Object... values) {
- if (object == null) {
- throw new NullPointerException(String.format(message, values));
- }
- return object;
- }
-
- // notEmpty array
- //---------------------------------------------------------------------------------
-
- /**
- * Validate that the specified argument array is neither {@code null}
- * nor a length of zero (no elements); otherwise throwing an exception
- * with the specified message.
- *
- *
Validate.notEmpty(myArray, "The array must not be empty");
- *
- * @param the array type
- * @param array the array to check, validated not null by this method
- * @param message the {@link String#format(String, Object...)} exception message if invalid, not null
- * @param values the optional values for the formatted exception message, null array not recommended
- * @return the validated array (never {@code null} method for chaining)
- * @throws NullPointerException if the array is {@code null}
- * @throws IllegalArgumentException if the array is empty
- * @see #notEmpty(Object[])
- */
- public static T[] notEmpty(T[] array, String message, Object... values) {
- if (array == null) {
- throw new NullPointerException(String.format(message, values));
- }
- if (array.length == 0) {
- throw new IllegalArgumentException(String.format(message, values));
- }
- return array;
- }
-
- /**
- * Validate that the specified argument array is neither {@code null}
- * nor a length of zero (no elements); otherwise throwing an exception.
- *
- *
Validate.notEmpty(myArray);
- *
- * The message in the exception is "The validated array is
- * empty".
- *
- * @param the array type
- * @param array the array to check, validated not null by this method
- * @return the validated array (never {@code null} method for chaining)
- * @throws NullPointerException if the array is {@code null}
- * @throws IllegalArgumentException if the array is empty
- * @see #notEmpty(Object[], String, Object...)
- */
- public static T[] notEmpty(T[] array) {
- return notEmpty(array, DEFAULT_NOT_EMPTY_ARRAY_EX_MESSAGE);
- }
-
- // notEmpty collection
- //---------------------------------------------------------------------------------
-
- /**
- * Validate that the specified argument collection is neither {@code null}
- * nor a size of zero (no elements); otherwise throwing an exception
- * with the specified message.
- *
- *
Validate.notEmpty(myCollection, "The collection must not be empty");
- *
- * @param the collection type
- * @param collection the collection to check, validated not null by this method
- * @param message the {@link String#format(String, Object...)} exception message if invalid, not null
- * @param values the optional values for the formatted exception message, null array not recommended
- * @return the validated collection (never {@code null} method for chaining)
- * @throws NullPointerException if the collection is {@code null}
- * @throws IllegalArgumentException if the collection is empty
- * @see #notEmpty(Object[])
- */
- public static > T notEmpty(T collection, String message, Object... values) {
- if (collection == null) {
- throw new NullPointerException(String.format(message, values));
- }
- if (collection.isEmpty()) {
- throw new IllegalArgumentException(String.format(message, values));
- }
- return collection;
- }
-
- /**
- * Validate that the specified argument collection is neither {@code null}
- * nor a size of zero (no elements); otherwise throwing an exception.
- *
- *
Validate.notEmpty(myCollection);
- *
- * The message in the exception is "The validated collection is
- * empty".
- *
- * @param the collection type
- * @param collection the collection to check, validated not null by this method
- * @return the validated collection (never {@code null} method for chaining)
- * @throws NullPointerException if the collection is {@code null}
- * @throws IllegalArgumentException if the collection is empty
- * @see #notEmpty(Collection, String, Object...)
- */
- public static > T notEmpty(T collection) {
- return notEmpty(collection, DEFAULT_NOT_EMPTY_COLLECTION_EX_MESSAGE);
- }
-
- // notEmpty map
- //---------------------------------------------------------------------------------
-
- /**
- * Validate that the specified argument map is neither {@code null}
- * nor a size of zero (no elements); otherwise throwing an exception
- * with the specified message.
- *
- *
Validate.notEmpty(myMap, "The map must not be empty");
- *
- * @param the map type
- * @param map the map to check, validated not null by this method
- * @param message the {@link String#format(String, Object...)} exception message if invalid, not null
- * @param values the optional values for the formatted exception message, null array not recommended
- * @return the validated map (never {@code null} method for chaining)
- * @throws NullPointerException if the map is {@code null}
- * @throws IllegalArgumentException if the map is empty
- * @see #notEmpty(Object[])
- */
- public static > T notEmpty(T map, String message, Object... values) {
- if (map == null) {
- throw new NullPointerException(String.format(message, values));
- }
- if (map.isEmpty()) {
- throw new IllegalArgumentException(String.format(message, values));
- }
- return map;
- }
-
- /**
- * Validate that the specified argument map is neither {@code null}
- * nor a size of zero (no elements); otherwise throwing an exception.
- *
- *
Validate.notEmpty(myMap);
- *
- * The message in the exception is "The validated map is
- * empty".
- *
- * @param the map type
- * @param map the map to check, validated not null by this method
- * @return the validated map (never {@code null} method for chaining)
- * @throws NullPointerException if the map is {@code null}
- * @throws IllegalArgumentException if the map is empty
- * @see #notEmpty(Map, String, Object...)
- */
- public static > T notEmpty(T map) {
- return notEmpty(map, DEFAULT_NOT_EMPTY_MAP_EX_MESSAGE);
- }
-
- // notEmpty string
- //---------------------------------------------------------------------------------
-
- /**
- * Validate that the specified argument character sequence is
- * neither {@code null} nor a length of zero (no characters);
- * otherwise throwing an exception with the specified message.
- *
- *
Validate.notEmpty(myString, "The string must not be empty");
- *
- * @param the character sequence type
- * @param chars the character sequence to check, validated not null by this method
- * @param message the {@link String#format(String, Object...)} exception message if invalid, not null
- * @param values the optional values for the formatted exception message, null array not recommended
- * @return the validated character sequence (never {@code null} method for chaining)
- * @throws NullPointerException if the character sequence is {@code null}
- * @throws IllegalArgumentException if the character sequence is empty
- * @see #notEmpty(CharSequence)
- */
- public static T notEmpty(T chars, String message, Object... values) {
- if (chars == null) {
- throw new NullPointerException(String.format(message, values));
- }
- if (chars.length() == 0) {
- throw new IllegalArgumentException(String.format(message, values));
- }
- return chars;
- }
-
- /**
- * Validate that the specified argument character sequence is
- * neither {@code null} nor a length of zero (no characters);
- * otherwise throwing an exception with the specified message.
- *
- *
Validate.notEmpty(myString);
- *
- * The message in the exception is "The validated
- * character sequence is empty".
- *
- * @param the character sequence type
- * @param chars the character sequence to check, validated not null by this method
- * @return the validated character sequence (never {@code null} method for chaining)
- * @throws NullPointerException if the character sequence is {@code null}
- * @throws IllegalArgumentException if the character sequence is empty
- * @see #notEmpty(CharSequence, String, Object...)
- */
- public static T notEmpty(T chars) {
- return notEmpty(chars, DEFAULT_NOT_EMPTY_CHAR_SEQUENCE_EX_MESSAGE);
- }
-
- // notBlank string
- //---------------------------------------------------------------------------------
-
- /**
- * Validate that the specified argument character sequence is
- * neither {@code null}, a length of zero (no characters), empty
- * nor whitespace; otherwise throwing an exception with the specified
- * message.
- *
- *
Validate.notBlank(myString, "The string must not be blank");
- *
- * @param the character sequence type
- * @param chars the character sequence to check, validated not null by this method
- * @param message the {@link String#format(String, Object...)} exception message if invalid, not null
- * @param values the optional values for the formatted exception message, null array not recommended
- * @return the validated character sequence (never {@code null} method for chaining)
- * @throws NullPointerException if the character sequence is {@code null}
- * @throws IllegalArgumentException if the character sequence is blank
- * @see #notBlank(CharSequence)
- *
- * @since 3.0
- */
- public static T notBlank(T chars, String message, Object... values) {
- if (chars == null) {
- throw new NullPointerException(String.format(message, values));
- }
- if (StringUtils.isBlank(chars)) {
- throw new IllegalArgumentException(String.format(message, values));
- }
- return chars;
- }
-
- /**
- * Validate that the specified argument character sequence is
- * neither {@code null}, a length of zero (no characters), empty
- * nor whitespace; otherwise throwing an exception.
- *
- *
Validate.notBlank(myString);
- *
- * The message in the exception is "The validated character
- * sequence is blank".
- *
- * @param the character sequence type
- * @param chars the character sequence to check, validated not null by this method
- * @return the validated character sequence (never {@code null} method for chaining)
- * @throws NullPointerException if the character sequence is {@code null}
- * @throws IllegalArgumentException if the character sequence is blank
- * @see #notBlank(CharSequence, String, Object...)
- *
- * @since 3.0
- */
- public static T notBlank(T chars) {
- return notBlank(chars, DEFAULT_NOT_BLANK_EX_MESSAGE);
- }
-
- // noNullElements array
- //---------------------------------------------------------------------------------
-
- /**
- * Validate that the specified argument array is neither
- * {@code null} nor contains any elements that are {@code null};
- * otherwise throwing an exception with the specified message.
- *
- *
Validate.noNullElements(myArray, "The array contain null at position %d");
- *
- * If the array is {@code null}, then the message in the exception
- * is "The validated object is null".
- *
- * If the array has a {@code null} element, then the iteration
- * index of the invalid element is appended to the {@code values}
- * argument.
- *
- * @param the array type
- * @param array the array to check, validated not null by this method
- * @param message the {@link String#format(String, Object...)} exception message if invalid, not null
- * @param values the optional values for the formatted exception message, null array not recommended
- * @return the validated array (never {@code null} method for chaining)
- * @throws NullPointerException if the array is {@code null}
- * @throws IllegalArgumentException if an element is {@code null}
- * @see #noNullElements(Object[])
- */
- public static T[] noNullElements(T[] array, String message, Object... values) {
- Validate.notNull(array);
- for (int i = 0; i < array.length; i++) {
- if (array[i] == null) {
- Object[] values2 = ArrayUtils.add(values, Integer.valueOf(i));
- throw new IllegalArgumentException(String.format(message, values2));
- }
- }
- return array;
- }
-
- /**
- * Validate that the specified argument array is neither
- * {@code null} nor contains any elements that are {@code null};
- * otherwise throwing an exception.
- *
- *
Validate.noNullElements(myArray);
- *
- * If the array is {@code null}, then the message in the exception
- * is "The validated object is null".
- *
- * If the array has a {@code null} element, then the message in the
- * exception is "The validated array contains null element at index:
- * " followed by the index.
- *
- * @param the array type
- * @param array the array to check, validated not null by this method
- * @return the validated array (never {@code null} method for chaining)
- * @throws NullPointerException if the array is {@code null}
- * @throws IllegalArgumentException if an element is {@code null}
- * @see #noNullElements(Object[], String, Object...)
- */
- public static T[] noNullElements(T[] array) {
- return noNullElements(array, DEFAULT_NO_NULL_ELEMENTS_ARRAY_EX_MESSAGE);
- }
-
- // noNullElements iterable
- //---------------------------------------------------------------------------------
-
- /**
- * Validate that the specified argument iterable is neither
- * {@code null} nor contains any elements that are {@code null};
- * otherwise throwing an exception with the specified message.
- *
- *
Validate.noNullElements(myCollection, "The collection contains null at position %d");
- *
- * If the iterable is {@code null}, then the message in the exception
- * is "The validated object is null".
- *
- * If the iterable has a {@code null} element, then the iteration
- * index of the invalid element is appended to the {@code values}
- * argument.
- *
- * @param the iterable type
- * @param iterable the iterable to check, validated not null by this method
- * @param message the {@link String#format(String, Object...)} exception message if invalid, not null
- * @param values the optional values for the formatted exception message, null array not recommended
- * @return the validated iterable (never {@code null} method for chaining)
- * @throws NullPointerException if the array is {@code null}
- * @throws IllegalArgumentException if an element is {@code null}
- * @see #noNullElements(Iterable)
- */
- public static > T noNullElements(T iterable, String message, Object... values) {
- Validate.notNull(iterable);
- int i = 0;
- for (Iterator> it = iterable.iterator(); it.hasNext(); i++) {
- if (it.next() == null) {
- Object[] values2 = ArrayUtils.addAll(values, Integer.valueOf(i));
- throw new IllegalArgumentException(String.format(message, values2));
- }
- }
- return iterable;
- }
-
- /**
- * Validate that the specified argument iterable is neither
- * {@code null} nor contains any elements that are {@code null};
- * otherwise throwing an exception.
- *
- *
Validate.noNullElements(myCollection);
- *
- * If the iterable is {@code null}, then the message in the exception
- * is "The validated object is null".
- *
- * If the array has a {@code null} element, then the message in the
- * exception is "The validated iterable contains null element at index:
- * " followed by the index.
- *
- * @param the iterable type
- * @param iterable the iterable to check, validated not null by this method
- * @return the validated iterable (never {@code null} method for chaining)
- * @throws NullPointerException if the array is {@code null}
- * @throws IllegalArgumentException if an element is {@code null}
- * @see #noNullElements(Iterable, String, Object...)
- */
- public static > T noNullElements(T iterable) {
- return noNullElements(iterable, DEFAULT_NO_NULL_ELEMENTS_COLLECTION_EX_MESSAGE);
- }
-
- // validIndex array
- //---------------------------------------------------------------------------------
-
- /**
- * Validates that the index is within the bounds of the argument
- * array; otherwise throwing an exception with the specified message.
- *
- * Validate.validIndex(myArray, 2, "The array index is invalid: ");
- *
- * If the array is {@code null}, then the message of the exception
- * is "The validated object is null".
- *
- * @param the array type
- * @param array the array to check, validated not null by this method
- * @param index the index to check
- * @param message the {@link String#format(String, Object...)} exception message if invalid, not null
- * @param values the optional values for the formatted exception message, null array not recommended
- * @return the validated array (never {@code null} for method chaining)
- * @throws NullPointerException if the array is {@code null}
- * @throws IndexOutOfBoundsException if the index is invalid
- * @see #validIndex(Object[], int)
- *
- * @since 3.0
- */
- public static T[] validIndex(T[] array, int index, String message, Object... values) {
- Validate.notNull(array);
- if (index < 0 || index >= array.length) {
- throw new IndexOutOfBoundsException(String.format(message, values));
- }
- return array;
- }
-
- /**
- * Validates that the index is within the bounds of the argument
- * array; otherwise throwing an exception.
- *
- * Validate.validIndex(myArray, 2);
- *
- * If the array is {@code null}, then the message of the exception
- * is "The validated object is null".
- *
- * If the index is invalid, then the message of the exception is
- * "The validated array index is invalid: " followed by the
- * index.
- *
- * @param the array type
- * @param array the array to check, validated not null by this method
- * @param index the index to check
- * @return the validated array (never {@code null} for method chaining)
- * @throws NullPointerException if the array is {@code null}
- * @throws IndexOutOfBoundsException if the index is invalid
- * @see #validIndex(Object[], int, String, Object...)
- *
- * @since 3.0
- */
- public static T[] validIndex(T[] array, int index) {
- return validIndex(array, index, DEFAULT_VALID_INDEX_ARRAY_EX_MESSAGE, Integer.valueOf(index));
- }
-
- // validIndex collection
- //---------------------------------------------------------------------------------
-
- /**
- * Validates that the index is within the bounds of the argument
- * collection; otherwise throwing an exception with the specified message.
- *
- * Validate.validIndex(myCollection, 2, "The collection index is invalid: ");
- *
- * If the collection is {@code null}, then the message of the
- * exception is "The validated object is null".
- *
- * @param the collection type
- * @param collection the collection to check, validated not null by this method
- * @param index the index to check
- * @param message the {@link String#format(String, Object...)} exception message if invalid, not null
- * @param values the optional values for the formatted exception message, null array not recommended
- * @return the validated collection (never {@code null} for chaining)
- * @throws NullPointerException if the collection is {@code null}
- * @throws IndexOutOfBoundsException if the index is invalid
- * @see #validIndex(Collection, int)
- *
- * @since 3.0
- */
- public static > T validIndex(T collection, int index, String message, Object... values) {
- Validate.notNull(collection);
- if (index < 0 || index >= collection.size()) {
- throw new IndexOutOfBoundsException(String.format(message, values));
- }
- return collection;
- }
-
- /**
- * Validates that the index is within the bounds of the argument
- * collection; otherwise throwing an exception.
- *
- * Validate.validIndex(myCollection, 2);
- *
- * If the index is invalid, then the message of the exception
- * is "The validated collection index is invalid: "
- * followed by the index.
- *
- * @param the collection type
- * @param collection the collection to check, validated not null by this method
- * @param index the index to check
- * @return the validated collection (never {@code null} for method chaining)
- * @throws NullPointerException if the collection is {@code null}
- * @throws IndexOutOfBoundsException if the index is invalid
- * @see #validIndex(Collection, int, String, Object...)
- *
- * @since 3.0
- */
- public static > T validIndex(T collection, int index) {
- return validIndex(collection, index, DEFAULT_VALID_INDEX_COLLECTION_EX_MESSAGE, Integer.valueOf(index));
- }
-
- // validIndex string
- //---------------------------------------------------------------------------------
-
- /**
- * Validates that the index is within the bounds of the argument
- * character sequence; otherwise throwing an exception with the
- * specified message.
- *
- * Validate.validIndex(myStr, 2, "The string index is invalid: ");
- *
- * If the character sequence is {@code null}, then the message
- * of the exception is "The validated object is null".
- *
- * @param the character sequence type
- * @param chars the character sequence to check, validated not null by this method
- * @param index the index to check
- * @param message the {@link String#format(String, Object...)} exception message if invalid, not null
- * @param values the optional values for the formatted exception message, null array not recommended
- * @return the validated character sequence (never {@code null} for method chaining)
- * @throws NullPointerException if the character sequence is {@code null}
- * @throws IndexOutOfBoundsException if the index is invalid
- * @see #validIndex(CharSequence, int)
- *
- * @since 3.0
- */
- public static T validIndex(T chars, int index, String message, Object... values) {
- Validate.notNull(chars);
- if (index < 0 || index >= chars.length()) {
- throw new IndexOutOfBoundsException(String.format(message, values));
- }
- return chars;
- }
-
- /**
- * Validates that the index is within the bounds of the argument
- * character sequence; otherwise throwing an exception.
- *
- * Validate.validIndex(myStr, 2);
- *
- * If the character sequence is {@code null}, then the message
- * of the exception is "The validated object is
- * null".
- *
- * If the index is invalid, then the message of the exception
- * is "The validated character sequence index is invalid: "
- * followed by the index.
- *
- * @param the character sequence type
- * @param chars the character sequence to check, validated not null by this method
- * @param index the index to check
- * @return the validated character sequence (never {@code null} for method chaining)
- * @throws NullPointerException if the character sequence is {@code null}
- * @throws IndexOutOfBoundsException if the index is invalid
- * @see #validIndex(CharSequence, int, String, Object...)
- *
- * @since 3.0
- */
- public static T validIndex(T chars, int index) {
- return validIndex(chars, index, DEFAULT_VALID_INDEX_CHAR_SEQUENCE_EX_MESSAGE, Integer.valueOf(index));
- }
-
- // validState
- //---------------------------------------------------------------------------------
-
- /**
- * Validate that the stateful condition is {@code true}; otherwise
- * throwing an exception. This method is useful when validating according
- * to an arbitrary boolean expression, such as validating a
- * primitive number or using your own custom validation expression.
- *
- *
- * Validate.validState(field > 0);
- * Validate.validState(this.isOk());
- *
- * The message of the exception is "The validated state is
- * false".
- *
- * @param expression the boolean expression to check
- * @throws IllegalStateException if expression is {@code false}
- * @see #validState(boolean, String, Object...)
- *
- * @since 3.0
- */
- public static void validState(boolean expression) {
- if (expression == false) {
- throw new IllegalStateException(DEFAULT_VALID_STATE_EX_MESSAGE);
- }
- }
-
- /**
- * Validate that the stateful condition is {@code true}; otherwise
- * throwing an exception with the specified message. This method is useful when
- * validating according to an arbitrary boolean expression, such as validating a
- * primitive number or using your own custom validation expression.
- *
- * Validate.validState(this.isOk(), "The state is not OK: %s", myObject);
- *
- * @param expression the boolean expression to check
- * @param message the {@link String#format(String, Object...)} exception message if invalid, not null
- * @param values the optional values for the formatted exception message, null array not recommended
- * @throws IllegalStateException if expression is {@code false}
- * @see #validState(boolean)
- *
- * @since 3.0
- */
- public static void validState(boolean expression, String message, Object... values) {
- if (expression == false) {
- throw new IllegalStateException(String.format(message, values));
- }
- }
-
- // matchesPattern
- //---------------------------------------------------------------------------------
-
- /**
- * Validate that the specified argument character sequence matches the specified regular
- * expression pattern; otherwise throwing an exception.
- *
- * Validate.matchesPattern("hi", "[a-z]*");
- *
- * The syntax of the pattern is the one used in the {@link Pattern} class.
- *
- * @param input the character sequence to validate, not null
- * @param pattern the regular expression pattern, not null
- * @throws IllegalArgumentException if the character sequence does not match the pattern
- * @see #matchesPattern(CharSequence, String, String, Object...)
- *
- * @since 3.0
- */
- public static void matchesPattern(CharSequence input, String pattern) {
- if (Pattern.matches(pattern, input) == false) {
- throw new IllegalArgumentException(String.format(DEFAULT_MATCHES_PATTERN_EX, input, pattern));
- }
- }
-
- /**
- * Validate that the specified argument character sequence matches the specified regular
- * expression pattern; otherwise throwing an exception with the specified message.
- *
- * Validate.matchesPattern("hi", "[a-z]*", "%s does not match %s", "hi" "[a-z]*");
- *
- * The syntax of the pattern is the one used in the {@link Pattern} class.
- *
- * @param input the character sequence to validate, not null
- * @param pattern the regular expression pattern, not null
- * @param message the {@link String#format(String, Object...)} exception message if invalid, not null
- * @param values the optional values for the formatted exception message, null array not recommended
- * @throws IllegalArgumentException if the character sequence does not match the pattern
- * @see #matchesPattern(CharSequence, String)
- *
- * @since 3.0
- */
- public static void matchesPattern(CharSequence input, String pattern, String message, Object... values) {
- if (Pattern.matches(pattern, input) == false) {
- throw new IllegalArgumentException(String.format(message, values));
- }
- }
-
- // inclusiveBetween
- //---------------------------------------------------------------------------------
-
- /**
- * Validate that the specified argument object fall between the two
- * inclusive values specified; otherwise, throws an exception.
- *
- * Validate.inclusiveBetween(0, 2, 1);
- *
- * @param the type of the argument object
- * @param start the inclusive start value, not null
- * @param end the inclusive end value, not null
- * @param value the object to validate, not null
- * @throws IllegalArgumentException if the value falls out of the boundaries
- * @see #inclusiveBetween(Object, Object, Comparable, String, Object...)
- *
- * @since 3.0
- */
- public static void inclusiveBetween(T start, T end, Comparable value) {
- if (value.compareTo(start) < 0 || value.compareTo(end) > 0) {
- throw new IllegalArgumentException(String.format(DEFAULT_INCLUSIVE_BETWEEN_EX_MESSAGE, value, start, end));
- }
- }
-
- /**
- * Validate that the specified argument object fall between the two
- * inclusive values specified; otherwise, throws an exception with the
- * specified message.
- *
- * Validate.inclusiveBetween(0, 2, 1, "Not in boundaries");
- *
- * @param the type of the argument object
- * @param start the inclusive start value, not null
- * @param end the inclusive end value, not null
- * @param value the object to validate, not null
- * @param message the {@link String#format(String, Object...)} exception message if invalid, not null
- * @param values the optional values for the formatted exception message, null array not recommended
- * @throws IllegalArgumentException if the value falls out of the boundaries
- * @see #inclusiveBetween(Object, Object, Comparable)
- *
- * @since 3.0
- */
- public static void inclusiveBetween(T start, T end, Comparable value, String message, Object... values) {
- if (value.compareTo(start) < 0 || value.compareTo(end) > 0) {
- throw new IllegalArgumentException(String.format(message, values));
- }
- }
-
- // exclusiveBetween
- //---------------------------------------------------------------------------------
-
- /**
- * Validate that the specified argument object fall between the two
- * exclusive values specified; otherwise, throws an exception.
- *
- * Validate.inclusiveBetween(0, 2, 1);
- *
- * @param the type of the argument object
- * @param start the exclusive start value, not null
- * @param end the exclusive end value, not null
- * @param value the object to validate, not null
- * @throws IllegalArgumentException if the value falls out of the boundaries
- * @see #exclusiveBetween(Object, Object, Comparable, String, Object...)
- *
- * @since 3.0
- */
- public static void exclusiveBetween(T start, T end, Comparable value) {
- if (value.compareTo(start) <= 0 || value.compareTo(end) >= 0) {
- throw new IllegalArgumentException(String.format(DEFAULT_EXCLUSIVE_BETWEEN_EX_MESSAGE, value, start, end));
- }
- }
-
- /**
- * Validate that the specified argument object fall between the two
- * exclusive values specified; otherwise, throws an exception with the
- * specified message.
- *
- * Validate.inclusiveBetween(0, 2, 1, "Not in boundaries");
- *
- * @param the type of the argument object
- * @param start the exclusive start value, not null
- * @param end the exclusive end value, not null
- * @param value the object to validate, not null
- * @param message the {@link String#format(String, Object...)} exception message if invalid, not null
- * @param values the optional values for the formatted exception message, null array not recommended
- * @throws IllegalArgumentException if the value falls out of the boundaries
- * @see #exclusiveBetween(Object, Object, Comparable)
- *
- * @since 3.0
- */
- public static void exclusiveBetween(T start, T end, Comparable value, String message, Object... values) {
- if (value.compareTo(start) <= 0 || value.compareTo(end) >= 0) {
- throw new IllegalArgumentException(String.format(message, values));
- }
- }
-
- // isInstanceOf
- //---------------------------------------------------------------------------------
-
- /**
- * Validates that the argument is an instance of the specified class, if not throws an exception.
- *
- * This method is useful when validating according to an arbitrary class
- *
- * Validate.isInstanceOf(OkClass.class, object);
- *
- * The message of the exception is "Expected type: {type}, actual: {obj_type}"
- *
- * @param type the class the object must be validated against, not null
- * @param obj the object to check, null throws an exception
- * @throws IllegalArgumentException if argument is not of specified class
- * @see #isInstanceOf(Class, Object, String, Object...)
- *
- * @since 3.0
- */
- public static void isInstanceOf(Class> type, Object obj) {
- if (type.isInstance(obj) == false) {
- throw new IllegalArgumentException(String.format(DEFAULT_IS_INSTANCE_OF_EX_MESSAGE, type.getName(),
- obj == null ? "null" : obj.getClass().getName()));
- }
- }
-
- /**
- * Validate that the argument is an instance of the specified class; otherwise
- * throwing an exception with the specified message. This method is useful when
- * validating according to an arbitrary class
- *
- * Validate.isInstanceOf(OkClass.classs, object, "Wrong class, object is of class %s",
- * object.getClass().getName());
- *
- * @param type the class the object must be validated against, not null
- * @param obj the object to check, null throws an exception
- * @param message the {@link String#format(String, Object...)} exception message if invalid, not null
- * @param values the optional values for the formatted exception message, null array not recommended
- * @throws IllegalArgumentException if argument is not of specified class
- * @see #isInstanceOf(Class, Object)
- *
- * @since 3.0
- */
- public static void isInstanceOf(Class> type, Object obj, String message, Object... values) {
- if (type.isInstance(obj) == false) {
- throw new IllegalArgumentException(String.format(message, values));
- }
- }
-
- // isAssignableFrom
- //---------------------------------------------------------------------------------
-
- /**
- * Validates that the argument can be converted to the specified class, if not, throws an exception.
- *
- * This method is useful when validating that there will be no casting errors.
- *
- * Validate.isAssignableFrom(SuperClass.class, object.getClass());
- *
- * The message format of the exception is "Cannot assign {type} to {superType}"
- *
- * @param superType the class the class must be validated against, not null
- * @param type the class to check, not null
- * @throws IllegalArgumentException if type argument is not assignable to the specified superType
- * @see #isAssignableFrom(Class, Class, String, Object...)
- *
- * @since 3.0
- */
- public static void isAssignableFrom(Class> superType, Class> type) {
- if (superType.isAssignableFrom(type) == false) {
- throw new IllegalArgumentException(String.format(DEFAULT_IS_ASSIGNABLE_EX_MESSAGE, type == null ? "null" : type.getName(),
- superType.getName()));
- }
- }
-
- /**
- * Validates that the argument can be converted to the specified class, if not throws an exception.
- *
- * This method is useful when validating if there will be no casting errors.
- *
- * Validate.isAssignableFrom(SuperClass.class, object.getClass());
- *
- * The message of the exception is "The validated object can not be converted to the"
- * followed by the name of the class and "class"
- *
- * @param superType the class the class must be validated against, not null
- * @param type the class to check, not null
- * @param message the {@link String#format(String, Object...)} exception message if invalid, not null
- * @param values the optional values for the formatted exception message, null array not recommended
- * @throws IllegalArgumentException if argument can not be converted to the specified class
- * @see #isAssignableFrom(Class, Class)
- */
- public static void isAssignableFrom(Class> superType, Class> type, String message, Object... values) {
- if (superType.isAssignableFrom(type) == false) {
- throw new IllegalArgumentException(String.format(message, values));
- }
- }
-}
diff --git a/core/src/main/java/external/org/apache/commons/lang3/builder/Builder.java b/core/src/main/java/external/org/apache/commons/lang3/builder/Builder.java
deleted file mode 100644
index a3b840cf..00000000
--- a/core/src/main/java/external/org/apache/commons/lang3/builder/Builder.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package external.org.apache.commons.lang3.builder;
-
-/**
- *
- * The Builder interface is designed to designate a class as a builder
- * object in the Builder design pattern. Builders are capable of creating and
- * configuring objects or results that normally take multiple steps to construct
- * or are very complex to derive.
- *
- *
- *
- * The builder interface defines a single method, {@link #build()}, that
- * classes must implement. The result of this method should be the final
- * configured object or result after all building operations are performed.
- *
- *
- *
- * It is a recommended practice that the methods supplied to configure the
- * object or result being built return a reference to {@code this} so that
- * method calls can be chained together.
- *
- *
- *
- * Example Builder:
- *
- * class FontBuilder implements Builder<Font> {
- * private Font font;
- *
- * public FontBuilder(String fontName) {
- * this.font = new Font(fontName, Font.PLAIN, 12);
- * }
- *
- * public FontBuilder bold() {
- * this.font = this.font.deriveFont(Font.BOLD);
- * return this; // Reference returned so calls can be chained
- * }
- *
- * public FontBuilder size(float pointSize) {
- * this.font = this.font.deriveFont(pointSize);
- * return this; // Reference returned so calls can be chained
- * }
- *
- * // Other Font construction methods
- *
- * public Font build() {
- * return this.font;
- * }
- * }
- *
- *
- * Example Builder Usage:
- *
- * Font bold14ptSansSerifFont = new FontBuilder(Font.SANS_SERIF).bold()
- * .size(14.0f)
- * .build();
- *
- *
- *
- * @param the type of object that the builder will construct or compute.
- *
- * @since 3.0
- * @version $Id: Builder.java 1088899 2011-04-05 05:31:27Z bayard $
- */
-public interface Builder {
-
- /**
- * Returns a reference to the object being constructed or result being
- * calculated by the builder.
- *
- * @return the object constructed or result calculated by the builder.
- */
- public T build();
-}
diff --git a/core/src/main/java/external/org/apache/commons/lang3/builder/CompareToBuilder.java b/core/src/main/java/external/org/apache/commons/lang3/builder/CompareToBuilder.java
deleted file mode 100644
index 9d06f589..00000000
--- a/core/src/main/java/external/org/apache/commons/lang3/builder/CompareToBuilder.java
+++ /dev/null
@@ -1,1020 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package external.org.apache.commons.lang3.builder;
-
-import java.lang.reflect.AccessibleObject;
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.util.Collection;
-import java.util.Comparator;
-
-import external.org.apache.commons.lang3.ArrayUtils;
-
-/**
- * Assists in implementing {@link java.lang.Comparable#compareTo(Object)} methods.
- *
- * It is consistent with equals(Object) and
- * hashcode() built with {@link EqualsBuilder} and
- * {@link HashCodeBuilder}.
- *
- * Two Objects that compare equal using equals(Object) should normally
- * also compare equal using compareTo(Object).
- *
- * All relevant fields should be included in the calculation of the
- * comparison. Derived fields may be ignored. The same fields, in the same
- * order, should be used in both compareTo(Object) and
- * equals(Object).
- *
- * To use this class write code as follows:
- *
- *
- * public class MyClass {
- * String field1;
- * int field2;
- * boolean field3;
- *
- * ...
- *
- * public int compareTo(Object o) {
- * MyClass myClass = (MyClass) o;
- * return new CompareToBuilder()
- * .appendSuper(super.compareTo(o)
- * .append(this.field1, myClass.field1)
- * .append(this.field2, myClass.field2)
- * .append(this.field3, myClass.field3)
- * .toComparison();
- * }
- * }
- *
- *
- * Alternatively, there are {@link #reflectionCompare(Object, Object) reflectionCompare} methods that use
- * reflection to determine the fields to append. Because fields can be private,
- * reflectionCompare uses {@link java.lang.reflect.AccessibleObject#setAccessible(boolean)} to
- * bypass normal access control checks. This will fail under a security manager,
- * unless the appropriate permissions are set up correctly. It is also
- * slower than appending explicitly.
- *
- * A typical implementation of compareTo(Object) using
- * reflectionCompare looks like:
-
- *
- * public int compareTo(Object o) {
- * return CompareToBuilder.reflectionCompare(this, o);
- * }
- *
- *
- * @see java.lang.Comparable
- * @see java.lang.Object#equals(Object)
- * @see java.lang.Object#hashCode()
- * @see EqualsBuilder
- * @see HashCodeBuilder
- * @since 1.0
- * @version $Id: CompareToBuilder.java 1199735 2011-11-09 13:11:07Z sebb $
- */
-public class CompareToBuilder implements Builder {
-
- /**
- * Current state of the comparison as appended fields are checked.
- */
- private int comparison;
-
- /**
- * Constructor for CompareToBuilder.
- *
- * Starts off assuming that the objects are equal. Multiple calls are
- * then made to the various append methods, followed by a call to
- * {@link #toComparison} to get the result.
- */
- public CompareToBuilder() {
- super();
- comparison = 0;
- }
-
- //-----------------------------------------------------------------------
- /**
- * Compares two Objects via reflection.
- *
- * Fields can be private, thus AccessibleObject.setAccessible
- * is used to bypass normal access control checks. This will fail under a
- * security manager unless the appropriate permissions are set.
- *
- *
- * Static fields will not be compared
- * Transient members will be not be compared, as they are likely derived
- * fields
- * Superclass fields will be compared
- *
- *
- * If both lhs and rhs are null,
- * they are considered equal.
- *
- * @param lhs left-hand object
- * @param rhs right-hand object
- * @return a negative integer, zero, or a positive integer as lhs
- * is less than, equal to, or greater than rhs
- * @throws NullPointerException if either (but not both) parameters are
- * null
- * @throws ClassCastException if rhs is not assignment-compatible
- * with lhs
- */
- public static int reflectionCompare(Object lhs, Object rhs) {
- return reflectionCompare(lhs, rhs, false, null);
- }
-
- /**
- * Compares two Objects via reflection.
- *
- * Fields can be private, thus AccessibleObject.setAccessible
- * is used to bypass normal access control checks. This will fail under a
- * security manager unless the appropriate permissions are set.
- *
- *
- * Static fields will not be compared
- * If compareTransients is true,
- * compares transient members. Otherwise ignores them, as they
- * are likely derived fields.
- * Superclass fields will be compared
- *
- *
- * If both lhs and rhs are null,
- * they are considered equal.
- *
- * @param lhs left-hand object
- * @param rhs right-hand object
- * @param compareTransients whether to compare transient fields
- * @return a negative integer, zero, or a positive integer as lhs
- * is less than, equal to, or greater than rhs
- * @throws NullPointerException if either lhs or rhs
- * (but not both) is null
- * @throws ClassCastException if rhs is not assignment-compatible
- * with lhs
- */
- public static int reflectionCompare(Object lhs, Object rhs, boolean compareTransients) {
- return reflectionCompare(lhs, rhs, compareTransients, null);
- }
-
- /**
- * Compares two Objects via reflection.
- *
- * Fields can be private, thus AccessibleObject.setAccessible
- * is used to bypass normal access control checks. This will fail under a
- * security manager unless the appropriate permissions are set.
- *
- *
- * Static fields will not be compared
- * If compareTransients is true,
- * compares transient members. Otherwise ignores them, as they
- * are likely derived fields.
- * Superclass fields will be compared
- *
- *
- * If both lhs and rhs are null,
- * they are considered equal.
- *
- * @param lhs left-hand object
- * @param rhs right-hand object
- * @param excludeFields Collection of String fields to exclude
- * @return a negative integer, zero, or a positive integer as lhs
- * is less than, equal to, or greater than rhs
- * @throws NullPointerException if either lhs or rhs
- * (but not both) is null
- * @throws ClassCastException if rhs is not assignment-compatible
- * with lhs
- * @since 2.2
- */
- public static int reflectionCompare(Object lhs, Object rhs, Collection excludeFields) {
- return reflectionCompare(lhs, rhs, ReflectionToStringBuilder.toNoNullStringArray(excludeFields));
- }
-
- /**
- * Compares two Objects via reflection.
- *
- * Fields can be private, thus AccessibleObject.setAccessible
- * is used to bypass normal access control checks. This will fail under a
- * security manager unless the appropriate permissions are set.
- *
- *
- * Static fields will not be compared
- * If compareTransients is true,
- * compares transient members. Otherwise ignores them, as they
- * are likely derived fields.
- * Superclass fields will be compared
- *
- *
- * If both lhs and rhs are null,
- * they are considered equal.
- *
- * @param lhs left-hand object
- * @param rhs right-hand object
- * @param excludeFields array of fields to exclude
- * @return a negative integer, zero, or a positive integer as lhs
- * is less than, equal to, or greater than rhs
- * @throws NullPointerException if either lhs or rhs
- * (but not both) is null
- * @throws ClassCastException if rhs is not assignment-compatible
- * with lhs
- * @since 2.2
- */
- public static int reflectionCompare(Object lhs, Object rhs, String... excludeFields) {
- return reflectionCompare(lhs, rhs, false, null, excludeFields);
- }
-
- /**
- * Compares two Objects via reflection.
- *
- * Fields can be private, thus AccessibleObject.setAccessible
- * is used to bypass normal access control checks. This will fail under a
- * security manager unless the appropriate permissions are set.
- *
- *
- * Static fields will not be compared
- * If the compareTransients is true,
- * compares transient members. Otherwise ignores them, as they
- * are likely derived fields.
- * Compares superclass fields up to and including reflectUpToClass.
- * If reflectUpToClass is null, compares all superclass fields.
- *
- *
- * If both lhs and rhs are null,
- * they are considered equal.
- *
- * @param lhs left-hand object
- * @param rhs right-hand object
- * @param compareTransients whether to compare transient fields
- * @param reflectUpToClass last superclass for which fields are compared
- * @param excludeFields fields to exclude
- * @return a negative integer, zero, or a positive integer as lhs
- * is less than, equal to, or greater than rhs
- * @throws NullPointerException if either lhs or rhs
- * (but not both) is null
- * @throws ClassCastException if rhs is not assignment-compatible
- * with lhs
- * @since 2.2 (2.0 as reflectionCompare(Object, Object, boolean, Class))
- */
- public static int reflectionCompare(
- Object lhs,
- Object rhs,
- boolean compareTransients,
- Class> reflectUpToClass,
- String... excludeFields) {
-
- if (lhs == rhs) {
- return 0;
- }
- if (lhs == null || rhs == null) {
- throw new NullPointerException();
- }
- Class> lhsClazz = lhs.getClass();
- if (!lhsClazz.isInstance(rhs)) {
- throw new ClassCastException();
- }
- CompareToBuilder compareToBuilder = new CompareToBuilder();
- reflectionAppend(lhs, rhs, lhsClazz, compareToBuilder, compareTransients, excludeFields);
- while (lhsClazz.getSuperclass() != null && lhsClazz != reflectUpToClass) {
- lhsClazz = lhsClazz.getSuperclass();
- reflectionAppend(lhs, rhs, lhsClazz, compareToBuilder, compareTransients, excludeFields);
- }
- return compareToBuilder.toComparison();
- }
-
- /**
- * Appends to builder the comparison of lhs
- * to rhs using the fields defined in clazz.
- *
- * @param lhs left-hand object
- * @param rhs right-hand object
- * @param clazz Class that defines fields to be compared
- * @param builder CompareToBuilder to append to
- * @param useTransients whether to compare transient fields
- * @param excludeFields fields to exclude
- */
- private static void reflectionAppend(
- Object lhs,
- Object rhs,
- Class> clazz,
- CompareToBuilder builder,
- boolean useTransients,
- String[] excludeFields) {
-
- Field[] fields = clazz.getDeclaredFields();
- AccessibleObject.setAccessible(fields, true);
- for (int i = 0; i < fields.length && builder.comparison == 0; i++) {
- Field f = fields[i];
- if (!ArrayUtils.contains(excludeFields, f.getName())
- && (f.getName().indexOf('$') == -1)
- && (useTransients || !Modifier.isTransient(f.getModifiers()))
- && (!Modifier.isStatic(f.getModifiers()))) {
- try {
- builder.append(f.get(lhs), f.get(rhs));
- } catch (IllegalAccessException e) {
- // This can't happen. Would get a Security exception instead.
- // Throw a runtime exception in case the impossible happens.
- throw new InternalError("Unexpected IllegalAccessException");
- }
- }
- }
- }
-
- //-----------------------------------------------------------------------
- /**
- * Appends to the builder the compareTo(Object)
- * result of the superclass.
- *
- * @param superCompareTo result of calling super.compareTo(Object)
- * @return this - used to chain append calls
- * @since 2.0
- */
- public CompareToBuilder appendSuper(int superCompareTo) {
- if (comparison != 0) {
- return this;
- }
- comparison = superCompareTo;
- return this;
- }
-
- //-----------------------------------------------------------------------
- /**
- * Appends to the builder the comparison of
- * two Objects.
- *
- *
- * Check if lhs == rhs
- * Check if either lhs or rhs is null,
- * a null object is less than a non-null object
- * Check the object contents
- *
- *
- * lhs must either be an array or implement {@link Comparable}.
- *
- * @param lhs left-hand object
- * @param rhs right-hand object
- * @return this - used to chain append calls
- * @throws ClassCastException if rhs is not assignment-compatible
- * with lhs
- */
- public CompareToBuilder append(Object lhs, Object rhs) {
- return append(lhs, rhs, null);
- }
-
- /**
- * Appends to the builder the comparison of
- * two Objects.
- *
- *
- * Check if lhs == rhs
- * Check if either lhs or rhs is null,
- * a null object is less than a non-null object
- * Check the object contents
- *
- *
- * If lhs is an array, array comparison methods will be used.
- * Otherwise comparator will be used to compare the objects.
- * If comparator is null, lhs must
- * implement {@link Comparable} instead.
- *
- * @param lhs left-hand object
- * @param rhs right-hand object
- * @param comparator Comparator used to compare the objects,
- * null means treat lhs as Comparable
- * @return this - used to chain append calls
- * @throws ClassCastException if rhs is not assignment-compatible
- * with lhs
- * @since 2.0
- */
- public CompareToBuilder append(Object lhs, Object rhs, Comparator> comparator) {
- if (comparison != 0) {
- return this;
- }
- if (lhs == rhs) {
- return this;
- }
- if (lhs == null) {
- comparison = -1;
- return this;
- }
- if (rhs == null) {
- comparison = +1;
- return this;
- }
- if (lhs.getClass().isArray()) {
- // switch on type of array, to dispatch to the correct handler
- // handles multi dimensional arrays
- // throws a ClassCastException if rhs is not the correct array type
- if (lhs instanceof long[]) {
- append((long[]) lhs, (long[]) rhs);
- } else if (lhs instanceof int[]) {
- append((int[]) lhs, (int[]) rhs);
- } else if (lhs instanceof short[]) {
- append((short[]) lhs, (short[]) rhs);
- } else if (lhs instanceof char[]) {
- append((char[]) lhs, (char[]) rhs);
- } else if (lhs instanceof byte[]) {
- append((byte[]) lhs, (byte[]) rhs);
- } else if (lhs instanceof double[]) {
- append((double[]) lhs, (double[]) rhs);
- } else if (lhs instanceof float[]) {
- append((float[]) lhs, (float[]) rhs);
- } else if (lhs instanceof boolean[]) {
- append((boolean[]) lhs, (boolean[]) rhs);
- } else {
- // not an array of primitives
- // throws a ClassCastException if rhs is not an array
- append((Object[]) lhs, (Object[]) rhs, comparator);
- }
- } else {
- // the simple case, not an array, just test the element
- if (comparator == null) {
- @SuppressWarnings("unchecked") // assume this can be done; if not throw CCE as per Javadoc
- final Comparable comparable = (Comparable) lhs;
- comparison = comparable.compareTo(rhs);
- } else {
- @SuppressWarnings("unchecked") // assume this can be done; if not throw CCE as per Javadoc
- final Comparator comparator2 = (Comparator) comparator;
- comparison = comparator2.compare(lhs, rhs);
- }
- }
- return this;
- }
-
- //-------------------------------------------------------------------------
- /**
- * Appends to the builder the comparison of
- * two longs.
- *
- * @param lhs left-hand value
- * @param rhs right-hand value
- * @return this - used to chain append calls
- */
- public CompareToBuilder append(long lhs, long rhs) {
- if (comparison != 0) {
- return this;
- }
- comparison = ((lhs < rhs) ? -1 : ((lhs > rhs) ? 1 : 0));
- return this;
- }
-
- /**
- * Appends to the builder the comparison of
- * two ints.
- *
- * @param lhs left-hand value
- * @param rhs right-hand value
- * @return this - used to chain append calls
- */
- public CompareToBuilder append(int lhs, int rhs) {
- if (comparison != 0) {
- return this;
- }
- comparison = ((lhs < rhs) ? -1 : ((lhs > rhs) ? 1 : 0));
- return this;
- }
-
- /**
- * Appends to the builder the comparison of
- * two shorts.
- *
- * @param lhs left-hand value
- * @param rhs right-hand value
- * @return this - used to chain append calls
- */
- public CompareToBuilder append(short lhs, short rhs) {
- if (comparison != 0) {
- return this;
- }
- comparison = ((lhs < rhs) ? -1 : ((lhs > rhs) ? 1 : 0));
- return this;
- }
-
- /**
- * Appends to the builder the comparison of
- * two chars.
- *
- * @param lhs left-hand value
- * @param rhs right-hand value
- * @return this - used to chain append calls
- */
- public CompareToBuilder append(char lhs, char rhs) {
- if (comparison != 0) {
- return this;
- }
- comparison = ((lhs < rhs) ? -1 : ((lhs > rhs) ? 1 : 0));
- return this;
- }
-
- /**
- * Appends to the builder the comparison of
- * two bytes.
- *
- * @param lhs left-hand value
- * @param rhs right-hand value
- * @return this - used to chain append calls
- */
- public CompareToBuilder append(byte lhs, byte rhs) {
- if (comparison != 0) {
- return this;
- }
- comparison = ((lhs < rhs) ? -1 : ((lhs > rhs) ? 1 : 0));
- return this;
- }
-
- /**
- * Appends to the builder the comparison of
- * two doubles.
- *
- * This handles NaNs, Infinities, and -0.0.
- *
- * It is compatible with the hash code generated by
- * HashCodeBuilder.
- *
- * @param lhs left-hand value
- * @param rhs right-hand value
- * @return this - used to chain append calls
- */
- public CompareToBuilder append(double lhs, double rhs) {
- if (comparison != 0) {
- return this;
- }
- comparison = Double.compare(lhs, rhs);
- return this;
- }
-
- /**
- * Appends to the builder the comparison of
- * two floats.
- *
- * This handles NaNs, Infinities, and -0.0.
- *
- * It is compatible with the hash code generated by
- * HashCodeBuilder.
- *
- * @param lhs left-hand value
- * @param rhs right-hand value
- * @return this - used to chain append calls
- */
- public CompareToBuilder append(float lhs, float rhs) {
- if (comparison != 0) {
- return this;
- }
- comparison = Float.compare(lhs, rhs);
- return this;
- }
-
- /**
- * Appends to the builder the comparison of
- * two booleanss.
- *
- * @param lhs left-hand value
- * @param rhs right-hand value
- * @return this - used to chain append calls
- */
- public CompareToBuilder append(boolean lhs, boolean rhs) {
- if (comparison != 0) {
- return this;
- }
- if (lhs == rhs) {
- return this;
- }
- if (lhs == false) {
- comparison = -1;
- } else {
- comparison = +1;
- }
- return this;
- }
-
- //-----------------------------------------------------------------------
- /**
- * Appends to the builder the deep comparison of
- * two Object arrays.
- *
- *
- * Check if arrays are the same using ==
- * Check if for null, null is less than non-null
- * Check array length, a short length array is less than a long length array
- * Check array contents element by element using {@link #append(Object, Object, Comparator)}
- *
- *
- * This method will also will be called for the top level of multi-dimensional,
- * ragged, and multi-typed arrays.
- *
- * @param lhs left-hand array
- * @param rhs right-hand array
- * @return this - used to chain append calls
- * @throws ClassCastException if rhs is not assignment-compatible
- * with lhs
- */
- public CompareToBuilder append(Object[] lhs, Object[] rhs) {
- return append(lhs, rhs, null);
- }
-
- /**
- * Appends to the builder the deep comparison of
- * two Object arrays.
- *
- *
- * Check if arrays are the same using ==
- * Check if for null, null is less than non-null
- * Check array length, a short length array is less than a long length array
- * Check array contents element by element using {@link #append(Object, Object, Comparator)}
- *
- *
- * This method will also will be called for the top level of multi-dimensional,
- * ragged, and multi-typed arrays.
- *
- * @param lhs left-hand array
- * @param rhs right-hand array
- * @param comparator Comparator to use to compare the array elements,
- * null means to treat lhs elements as Comparable.
- * @return this - used to chain append calls
- * @throws ClassCastException if rhs is not assignment-compatible
- * with lhs
- * @since 2.0
- */
- public CompareToBuilder append(Object[] lhs, Object[] rhs, Comparator> comparator) {
- if (comparison != 0) {
- return this;
- }
- if (lhs == rhs) {
- return this;
- }
- if (lhs == null) {
- comparison = -1;
- return this;
- }
- if (rhs == null) {
- comparison = +1;
- return this;
- }
- if (lhs.length != rhs.length) {
- comparison = (lhs.length < rhs.length) ? -1 : +1;
- return this;
- }
- for (int i = 0; i < lhs.length && comparison == 0; i++) {
- append(lhs[i], rhs[i], comparator);
- }
- return this;
- }
-
- /**
- * Appends to the builder the deep comparison of
- * two long arrays.
- *
- *
- * Check if arrays are the same using ==
- * Check if for null, null is less than non-null
- * Check array length, a shorter length array is less than a longer length array
- * Check array contents element by element using {@link #append(long, long)}
- *
- *
- * @param lhs left-hand array
- * @param rhs right-hand array
- * @return this - used to chain append calls
- */
- public CompareToBuilder append(long[] lhs, long[] rhs) {
- if (comparison != 0) {
- return this;
- }
- if (lhs == rhs) {
- return this;
- }
- if (lhs == null) {
- comparison = -1;
- return this;
- }
- if (rhs == null) {
- comparison = +1;
- return this;
- }
- if (lhs.length != rhs.length) {
- comparison = (lhs.length < rhs.length) ? -1 : +1;
- return this;
- }
- for (int i = 0; i < lhs.length && comparison == 0; i++) {
- append(lhs[i], rhs[i]);
- }
- return this;
- }
-
- /**
- * Appends to the builder the deep comparison of
- * two int arrays.
- *
- *
- * Check if arrays are the same using ==
- * Check if for null, null is less than non-null
- * Check array length, a shorter length array is less than a longer length array
- * Check array contents element by element using {@link #append(int, int)}
- *
- *
- * @param lhs left-hand array
- * @param rhs right-hand array
- * @return this - used to chain append calls
- */
- public CompareToBuilder append(int[] lhs, int[] rhs) {
- if (comparison != 0) {
- return this;
- }
- if (lhs == rhs) {
- return this;
- }
- if (lhs == null) {
- comparison = -1;
- return this;
- }
- if (rhs == null) {
- comparison = +1;
- return this;
- }
- if (lhs.length != rhs.length) {
- comparison = (lhs.length < rhs.length) ? -1 : +1;
- return this;
- }
- for (int i = 0; i < lhs.length && comparison == 0; i++) {
- append(lhs[i], rhs[i]);
- }
- return this;
- }
-
- /**
- * Appends to the builder the deep comparison of
- * two short arrays.
- *
- *
- * Check if arrays are the same using ==
- * Check if for null, null is less than non-null
- * Check array length, a shorter length array is less than a longer length array
- * Check array contents element by element using {@link #append(short, short)}
- *
- *
- * @param lhs left-hand array
- * @param rhs right-hand array
- * @return this - used to chain append calls
- */
- public CompareToBuilder append(short[] lhs, short[] rhs) {
- if (comparison != 0) {
- return this;
- }
- if (lhs == rhs) {
- return this;
- }
- if (lhs == null) {
- comparison = -1;
- return this;
- }
- if (rhs == null) {
- comparison = +1;
- return this;
- }
- if (lhs.length != rhs.length) {
- comparison = (lhs.length < rhs.length) ? -1 : +1;
- return this;
- }
- for (int i = 0; i < lhs.length && comparison == 0; i++) {
- append(lhs[i], rhs[i]);
- }
- return this;
- }
-
- /**
- * Appends to the builder the deep comparison of
- * two char arrays.
- *
- *
- * Check if arrays are the same using ==
- * Check if for null, null is less than non-null
- * Check array length, a shorter length array is less than a longer length array
- * Check array contents element by element using {@link #append(char, char)}
- *
- *
- * @param lhs left-hand array
- * @param rhs right-hand array
- * @return this - used to chain append calls
- */
- public CompareToBuilder append(char[] lhs, char[] rhs) {
- if (comparison != 0) {
- return this;
- }
- if (lhs == rhs) {
- return this;
- }
- if (lhs == null) {
- comparison = -1;
- return this;
- }
- if (rhs == null) {
- comparison = +1;
- return this;
- }
- if (lhs.length != rhs.length) {
- comparison = (lhs.length < rhs.length) ? -1 : +1;
- return this;
- }
- for (int i = 0; i < lhs.length && comparison == 0; i++) {
- append(lhs[i], rhs[i]);
- }
- return this;
- }
-
- /**
- * Appends to the builder the deep comparison of
- * two byte arrays.
- *
- *
- * Check if arrays are the same using ==
- * Check if for null, null is less than non-null
- * Check array length, a shorter length array is less than a longer length array
- * Check array contents element by element using {@link #append(byte, byte)}
- *
- *
- * @param lhs left-hand array
- * @param rhs right-hand array
- * @return this - used to chain append calls
- */
- public CompareToBuilder append(byte[] lhs, byte[] rhs) {
- if (comparison != 0) {
- return this;
- }
- if (lhs == rhs) {
- return this;
- }
- if (lhs == null) {
- comparison = -1;
- return this;
- }
- if (rhs == null) {
- comparison = +1;
- return this;
- }
- if (lhs.length != rhs.length) {
- comparison = (lhs.length < rhs.length) ? -1 : +1;
- return this;
- }
- for (int i = 0; i < lhs.length && comparison == 0; i++) {
- append(lhs[i], rhs[i]);
- }
- return this;
- }
-
- /**
- * Appends to the builder the deep comparison of
- * two double arrays.
- *
- *
- * Check if arrays are the same using ==
- * Check if for null, null is less than non-null
- * Check array length, a shorter length array is less than a longer length array
- * Check array contents element by element using {@link #append(double, double)}
- *
- *
- * @param lhs left-hand array
- * @param rhs right-hand array
- * @return this - used to chain append calls
- */
- public CompareToBuilder append(double[] lhs, double[] rhs) {
- if (comparison != 0) {
- return this;
- }
- if (lhs == rhs) {
- return this;
- }
- if (lhs == null) {
- comparison = -1;
- return this;
- }
- if (rhs == null) {
- comparison = +1;
- return this;
- }
- if (lhs.length != rhs.length) {
- comparison = (lhs.length < rhs.length) ? -1 : +1;
- return this;
- }
- for (int i = 0; i < lhs.length && comparison == 0; i++) {
- append(lhs[i], rhs[i]);
- }
- return this;
- }
-
- /**
- * Appends to the builder the deep comparison of
- * two float arrays.
- *
- *
- * Check if arrays are the same using ==
- * Check if for null, null is less than non-null
- * Check array length, a shorter length array is less than a longer length array
- * Check array contents element by element using {@link #append(float, float)}
- *
- *
- * @param lhs left-hand array
- * @param rhs right-hand array
- * @return this - used to chain append calls
- */
- public CompareToBuilder append(float[] lhs, float[] rhs) {
- if (comparison != 0) {
- return this;
- }
- if (lhs == rhs) {
- return this;
- }
- if (lhs == null) {
- comparison = -1;
- return this;
- }
- if (rhs == null) {
- comparison = +1;
- return this;
- }
- if (lhs.length != rhs.length) {
- comparison = (lhs.length < rhs.length) ? -1 : +1;
- return this;
- }
- for (int i = 0; i < lhs.length && comparison == 0; i++) {
- append(lhs[i], rhs[i]);
- }
- return this;
- }
-
- /**
- * Appends to the builder the deep comparison of
- * two boolean arrays.
- *
- *
- * Check if arrays are the same using ==
- * Check if for null, null is less than non-null
- * Check array length, a shorter length array is less than a longer length array
- * Check array contents element by element using {@link #append(boolean, boolean)}
- *
- *
- * @param lhs left-hand array
- * @param rhs right-hand array
- * @return this - used to chain append calls
- */
- public CompareToBuilder append(boolean[] lhs, boolean[] rhs) {
- if (comparison != 0) {
- return this;
- }
- if (lhs == rhs) {
- return this;
- }
- if (lhs == null) {
- comparison = -1;
- return this;
- }
- if (rhs == null) {
- comparison = +1;
- return this;
- }
- if (lhs.length != rhs.length) {
- comparison = (lhs.length < rhs.length) ? -1 : +1;
- return this;
- }
- for (int i = 0; i < lhs.length && comparison == 0; i++) {
- append(lhs[i], rhs[i]);
- }
- return this;
- }
-
- //-----------------------------------------------------------------------
- /**
- * Returns a negative integer, a positive integer, or zero as
- * the builder has judged the "left-hand" side
- * as less than, greater than, or equal to the "right-hand"
- * side.
- *
- * @return final comparison result
- * @see #build()
- */
- public int toComparison() {
- return comparison;
- }
-
- /**
- * Returns a negative Integer, a positive Integer, or zero as
- * the builder has judged the "left-hand" side
- * as less than, greater than, or equal to the "right-hand"
- * side.
- *
- * @return final comparison result as an Integer
- * @see #toComparison()
- * @since 3.0
- */
- public Integer build() {
- return Integer.valueOf(toComparison());
- }
-}
-
diff --git a/core/src/main/java/external/org/apache/commons/lang3/builder/EqualsBuilder.java b/core/src/main/java/external/org/apache/commons/lang3/builder/EqualsBuilder.java
deleted file mode 100644
index c8a459c5..00000000
--- a/core/src/main/java/external/org/apache/commons/lang3/builder/EqualsBuilder.java
+++ /dev/null
@@ -1,945 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package external.org.apache.commons.lang3.builder;
-
-import java.lang.reflect.AccessibleObject;
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
-
-
-import external.org.apache.commons.lang3.ArrayUtils;
-import external.org.apache.commons.lang3.tuple.Pair;
-
-/**
- * Assists in implementing {@link Object#equals(Object)} methods.
- *
- * This class provides methods to build a good equals method for any
- * class. It follows rules laid out in
- * Effective Java
- * , by Joshua Bloch. In particular the rule for comparing doubles,
- * floats, and arrays can be tricky. Also, making sure that
- * equals() and hashCode() are consistent can be
- * difficult.
- *
- * Two Objects that compare as equals must generate the same hash code,
- * but two Objects with the same hash code do not have to be equal.
- *
- * All relevant fields should be included in the calculation of equals.
- * Derived fields may be ignored. In particular, any field used in
- * generating a hash code must be used in the equals method, and vice
- * versa.
- *
- * Typical use for the code is as follows:
- *
- * public boolean equals(Object obj) {
- * if (obj == null) { return false; }
- * if (obj == this) { return true; }
- * if (obj.getClass() != getClass()) {
- * return false;
- * }
- * MyClass rhs = (MyClass) obj;
- * return new EqualsBuilder()
- * .appendSuper(super.equals(obj))
- * .append(field1, rhs.field1)
- * .append(field2, rhs.field2)
- * .append(field3, rhs.field3)
- * .isEquals();
- * }
- *
- *
- * Alternatively, there is a method that uses reflection to determine
- * the fields to test. Because these fields are usually private, the method,
- * reflectionEquals, uses AccessibleObject.setAccessible to
- * change the visibility of the fields. This will fail under a security
- * manager, unless the appropriate permissions are set up correctly. It is
- * also slower than testing explicitly.
- *
- * A typical invocation for this method would look like:
- *
- * public boolean equals(Object obj) {
- * return EqualsBuilder.reflectionEquals(this, obj);
- * }
- *
- *
- * @since 1.0
- * @version $Id: EqualsBuilder.java 1091531 2011-04-12 18:29:49Z ggregory $
- */
-public class EqualsBuilder implements Builder {
-
- /**
- *
- * A registry of objects used by reflection methods to detect cyclical object references and avoid infinite loops.
- *
- *
- * @since 3.0
- */
- private static final ThreadLocal>> REGISTRY = new ThreadLocal>>();
-
- /*
- * NOTE: we cannot store the actual objects in a HashSet, as that would use the very hashCode()
- * we are in the process of calculating.
- *
- * So we generate a one-to-one mapping from the original object to a new object.
- *
- * Now HashSet uses equals() to determine if two elements with the same hashcode really
- * are equal, so we also need to ensure that the replacement objects are only equal
- * if the original objects are identical.
- *
- * The original implementation (2.4 and before) used the System.indentityHashCode()
- * method - however this is not guaranteed to generate unique ids (e.g. LANG-459)
- *
- * We now use the IDKey helper class (adapted from org.apache.axis.utils.IDKey)
- * to disambiguate the duplicate ids.
- */
-
- /**
- *
- * Returns the registry of object pairs being traversed by the reflection
- * methods in the current thread.
- *
- *
- * @return Set the registry of objects being traversed
- * @since 3.0
- */
- static Set> getRegistry() {
- return REGISTRY.get();
- }
-
- /**
- *
- * Converters value pair into a register pair.
- *
- *
- * @param lhs this object
- * @param rhs the other object
- *
- * @return the pair
- */
- static Pair getRegisterPair(Object lhs, Object rhs) {
- IDKey left = new IDKey(lhs);
- IDKey right = new IDKey(rhs);
- return Pair.of(left, right);
- }
-
- /**
- *
- * Returns true if the registry contains the given object pair.
- * Used by the reflection methods to avoid infinite loops.
- * Objects might be swapped therefore a check is needed if the object pair
- * is registered in given or swapped order.
- *
- *
- * @param lhs this object to lookup in registry
- * @param rhs the other object to lookup on registry
- * @return boolean true if the registry contains the given object.
- * @since 3.0
- */
- static boolean isRegistered(Object lhs, Object rhs) {
- Set> registry = getRegistry();
- Pair pair = getRegisterPair(lhs, rhs);
- Pair swappedPair = Pair.of(pair.getLeft(), pair.getRight());
-
- return registry != null
- && (registry.contains(pair) || registry.contains(swappedPair));
- }
-
- /**
- *
- * Registers the given object pair.
- * Used by the reflection methods to avoid infinite loops.
- *
- *
- * @param lhs this object to register
- * @param rhs the other object to register
- */
- static void register(Object lhs, Object rhs) {
- synchronized (EqualsBuilder.class) {
- if (getRegistry() == null) {
- REGISTRY.set(new HashSet>());
- }
- }
-
- Set> registry = getRegistry();
- Pair pair = getRegisterPair(lhs, rhs);
- registry.add(pair);
- }
-
- /**
- *
- * Unregisters the given object pair.
- *
- *
- *
- * Used by the reflection methods to avoid infinite loops.
- *
- * @param lhs this object to unregister
- * @param rhs the other object to unregister
- * @since 3.0
- */
- static void unregister(Object lhs, Object rhs) {
- Set> registry = getRegistry();
- if (registry != null) {
- Pair pair = getRegisterPair(lhs, rhs);
- registry.remove(pair);
- synchronized (EqualsBuilder.class) {
- //read again
- registry = getRegistry();
- if (registry != null && registry.isEmpty()) {
- REGISTRY.remove();
- }
- }
- }
- }
-
- /**
- * If the fields tested are equals.
- * The default value is true.
- */
- private boolean isEquals = true;
-
- /**
- * Constructor for EqualsBuilder.
- *
- * Starts off assuming that equals is true.
- * @see Object#equals(Object)
- */
- public EqualsBuilder() {
- // do nothing for now.
- }
-
- //-------------------------------------------------------------------------
-
- /**
- * This method uses reflection to determine if the two Objects
- * are equal.
- *
- * It uses AccessibleObject.setAccessible to gain access to private
- * fields. This means that it will throw a security exception if run under
- * a security manager, if the permissions are not set up correctly. It is also
- * not as efficient as testing explicitly.
- *
- * Transient members will be not be tested, as they are likely derived
- * fields, and not part of the value of the Object.
- *
- * Static fields will not be tested. Superclass fields will be included.
- *
- * @param lhs this object
- * @param rhs the other object
- * @param excludeFields Collection of String field names to exclude from testing
- * @return true if the two Objects have tested equals.
- */
- public static boolean reflectionEquals(Object lhs, Object rhs, Collection excludeFields) {
- return reflectionEquals(lhs, rhs, ReflectionToStringBuilder.toNoNullStringArray(excludeFields));
- }
-
- /**
- * This method uses reflection to determine if the two Objects
- * are equal.
- *
- * It uses AccessibleObject.setAccessible to gain access to private
- * fields. This means that it will throw a security exception if run under
- * a security manager, if the permissions are not set up correctly. It is also
- * not as efficient as testing explicitly.
- *
- * Transient members will be not be tested, as they are likely derived
- * fields, and not part of the value of the Object.
- *
- * Static fields will not be tested. Superclass fields will be included.
- *
- * @param lhs this object
- * @param rhs the other object
- * @param excludeFields array of field names to exclude from testing
- * @return true if the two Objects have tested equals.
- */
- public static boolean reflectionEquals(Object lhs, Object rhs, String... excludeFields) {
- return reflectionEquals(lhs, rhs, false, null, excludeFields);
- }
-
- /**
- * This method uses reflection to determine if the two Objects
- * are equal.
- *
- * It uses AccessibleObject.setAccessible to gain access to private
- * fields. This means that it will throw a security exception if run under
- * a security manager, if the permissions are not set up correctly. It is also
- * not as efficient as testing explicitly.
- *
- * If the TestTransients parameter is set to true, transient
- * members will be tested, otherwise they are ignored, as they are likely
- * derived fields, and not part of the value of the Object.
- *
- * Static fields will not be tested. Superclass fields will be included.
- *
- * @param lhs this object
- * @param rhs the other object
- * @param testTransients whether to include transient fields
- * @return true if the two Objects have tested equals.
- */
- public static boolean reflectionEquals(Object lhs, Object rhs, boolean testTransients) {
- return reflectionEquals(lhs, rhs, testTransients, null);
- }
-
- /**
- * This method uses reflection to determine if the two Objects
- * are equal.
- *
- * It uses AccessibleObject.setAccessible to gain access to private
- * fields. This means that it will throw a security exception if run under
- * a security manager, if the permissions are not set up correctly. It is also
- * not as efficient as testing explicitly.
- *
- * If the testTransients parameter is set to true, transient
- * members will be tested, otherwise they are ignored, as they are likely
- * derived fields, and not part of the value of the Object.
- *
- * Static fields will not be included. Superclass fields will be appended
- * up to and including the specified superclass. A null superclass is treated
- * as java.lang.Object.
- *
- * @param lhs this object
- * @param rhs the other object
- * @param testTransients whether to include transient fields
- * @param reflectUpToClass the superclass to reflect up to (inclusive),
- * may be null
- * @param excludeFields array of field names to exclude from testing
- * @return true if the two Objects have tested equals.
- * @since 2.0
- */
- public static boolean reflectionEquals(Object lhs, Object rhs, boolean testTransients, Class> reflectUpToClass,
- String... excludeFields) {
- if (lhs == rhs) {
- return true;
- }
- if (lhs == null || rhs == null) {
- return false;
- }
- // Find the leaf class since there may be transients in the leaf
- // class or in classes between the leaf and root.
- // If we are not testing transients or a subclass has no ivars,
- // then a subclass can test equals to a superclass.
- Class> lhsClass = lhs.getClass();
- Class> rhsClass = rhs.getClass();
- Class> testClass;
- if (lhsClass.isInstance(rhs)) {
- testClass = lhsClass;
- if (!rhsClass.isInstance(lhs)) {
- // rhsClass is a subclass of lhsClass
- testClass = rhsClass;
- }
- } else if (rhsClass.isInstance(lhs)) {
- testClass = rhsClass;
- if (!lhsClass.isInstance(rhs)) {
- // lhsClass is a subclass of rhsClass
- testClass = lhsClass;
- }
- } else {
- // The two classes are not related.
- return false;
- }
- EqualsBuilder equalsBuilder = new EqualsBuilder();
- try {
- reflectionAppend(lhs, rhs, testClass, equalsBuilder, testTransients, excludeFields);
- while (testClass.getSuperclass() != null && testClass != reflectUpToClass) {
- testClass = testClass.getSuperclass();
- reflectionAppend(lhs, rhs, testClass, equalsBuilder, testTransients, excludeFields);
- }
- } catch (IllegalArgumentException e) {
- // In this case, we tried to test a subclass vs. a superclass and
- // the subclass has ivars or the ivars are transient and
- // we are testing transients.
- // If a subclass has ivars that we are trying to test them, we get an
- // exception and we know that the objects are not equal.
- return false;
- }
- return equalsBuilder.isEquals();
- }
-
- /**
- * Appends the fields and values defined by the given object of the
- * given Class.
- *
- * @param lhs the left hand object
- * @param rhs the right hand object
- * @param clazz the class to append details of
- * @param builder the builder to append to
- * @param useTransients whether to test transient fields
- * @param excludeFields array of field names to exclude from testing
- */
- private static void reflectionAppend(
- Object lhs,
- Object rhs,
- Class> clazz,
- EqualsBuilder builder,
- boolean useTransients,
- String[] excludeFields) {
-
- if (isRegistered(lhs, rhs)) {
- return;
- }
-
- try {
- register(lhs, rhs);
- Field[] fields = clazz.getDeclaredFields();
- AccessibleObject.setAccessible(fields, true);
- for (int i = 0; i < fields.length && builder.isEquals; i++) {
- Field f = fields[i];
- if (!ArrayUtils.contains(excludeFields, f.getName())
- && (f.getName().indexOf('$') == -1)
- && (useTransients || !Modifier.isTransient(f.getModifiers()))
- && (!Modifier.isStatic(f.getModifiers()))) {
- try {
- builder.append(f.get(lhs), f.get(rhs));
- } catch (IllegalAccessException e) {
- //this can't happen. Would get a Security exception instead
- //throw a runtime exception in case the impossible happens.
- throw new InternalError("Unexpected IllegalAccessException");
- }
- }
- }
- } finally {
- unregister(lhs, rhs);
- }
- }
-
- //-------------------------------------------------------------------------
-
- /**
- * Adds the result of super.equals() to this builder.
- *
- * @param superEquals the result of calling super.equals()
- * @return EqualsBuilder - used to chain calls.
- * @since 2.0
- */
- public EqualsBuilder appendSuper(boolean superEquals) {
- if (isEquals == false) {
- return this;
- }
- isEquals = superEquals;
- return this;
- }
-
- //-------------------------------------------------------------------------
-
- /**
- * Test if two Objects are equal using their
- * equals method.
- *
- * @param lhs the left hand object
- * @param rhs the right hand object
- * @return EqualsBuilder - used to chain calls.
- */
- public EqualsBuilder append(Object lhs, Object rhs) {
- if (isEquals == false) {
- return this;
- }
- if (lhs == rhs) {
- return this;
- }
- if (lhs == null || rhs == null) {
- this.setEquals(false);
- return this;
- }
- Class> lhsClass = lhs.getClass();
- if (!lhsClass.isArray()) {
- // The simple case, not an array, just test the element
- isEquals = lhs.equals(rhs);
- } else if (lhs.getClass() != rhs.getClass()) {
- // Here when we compare different dimensions, for example: a boolean[][] to a boolean[]
- this.setEquals(false);
- }
- // 'Switch' on type of array, to dispatch to the correct handler
- // This handles multi dimensional arrays of the same depth
- else if (lhs instanceof long[]) {
- append((long[]) lhs, (long[]) rhs);
- } else if (lhs instanceof int[]) {
- append((int[]) lhs, (int[]) rhs);
- } else if (lhs instanceof short[]) {
- append((short[]) lhs, (short[]) rhs);
- } else if (lhs instanceof char[]) {
- append((char[]) lhs, (char[]) rhs);
- } else if (lhs instanceof byte[]) {
- append((byte[]) lhs, (byte[]) rhs);
- } else if (lhs instanceof double[]) {
- append((double[]) lhs, (double[]) rhs);
- } else if (lhs instanceof float[]) {
- append((float[]) lhs, (float[]) rhs);
- } else if (lhs instanceof boolean[]) {
- append((boolean[]) lhs, (boolean[]) rhs);
- } else {
- // Not an array of primitives
- append((Object[]) lhs, (Object[]) rhs);
- }
- return this;
- }
-
- /**
- *
- * Test if two long s are equal.
- *
- *
- * @param lhs
- * the left hand long
- * @param rhs
- * the right hand long
- * @return EqualsBuilder - used to chain calls.
- */
- public EqualsBuilder append(long lhs, long rhs) {
- if (isEquals == false) {
- return this;
- }
- isEquals = (lhs == rhs);
- return this;
- }
-
- /**
- * Test if two ints are equal.
- *
- * @param lhs the left hand int
- * @param rhs the right hand int
- * @return EqualsBuilder - used to chain calls.
- */
- public EqualsBuilder append(int lhs, int rhs) {
- if (isEquals == false) {
- return this;
- }
- isEquals = (lhs == rhs);
- return this;
- }
-
- /**
- * Test if two shorts are equal.
- *
- * @param lhs the left hand short
- * @param rhs the right hand short
- * @return EqualsBuilder - used to chain calls.
- */
- public EqualsBuilder append(short lhs, short rhs) {
- if (isEquals == false) {
- return this;
- }
- isEquals = (lhs == rhs);
- return this;
- }
-
- /**
- * Test if two chars are equal.
- *
- * @param lhs the left hand char
- * @param rhs the right hand char
- * @return EqualsBuilder - used to chain calls.
- */
- public EqualsBuilder append(char lhs, char rhs) {
- if (isEquals == false) {
- return this;
- }
- isEquals = (lhs == rhs);
- return this;
- }
-
- /**
- * Test if two bytes are equal.
- *
- * @param lhs the left hand byte
- * @param rhs the right hand byte
- * @return EqualsBuilder - used to chain calls.
- */
- public EqualsBuilder append(byte lhs, byte rhs) {
- if (isEquals == false) {
- return this;
- }
- isEquals = (lhs == rhs);
- return this;
- }
-
- /**
- * Test if two doubles are equal by testing that the
- * pattern of bits returned by doubleToLong are equal.
- *
- * This handles NaNs, Infinities, and -0.0.
- *
- * It is compatible with the hash code generated by
- * HashCodeBuilder.
- *
- * @param lhs the left hand double
- * @param rhs the right hand double
- * @return EqualsBuilder - used to chain calls.
- */
- public EqualsBuilder append(double lhs, double rhs) {
- if (isEquals == false) {
- return this;
- }
- return append(Double.doubleToLongBits(lhs), Double.doubleToLongBits(rhs));
- }
-
- /**
- * Test if two floats are equal byt testing that the
- * pattern of bits returned by doubleToLong are equal.
- *
- * This handles NaNs, Infinities, and -0.0.
- *
- * It is compatible with the hash code generated by
- * HashCodeBuilder.
- *
- * @param lhs the left hand float
- * @param rhs the right hand float
- * @return EqualsBuilder - used to chain calls.
- */
- public EqualsBuilder append(float lhs, float rhs) {
- if (isEquals == false) {
- return this;
- }
- return append(Float.floatToIntBits(lhs), Float.floatToIntBits(rhs));
- }
-
- /**
- * Test if two booleanss are equal.
- *
- * @param lhs the left hand boolean
- * @param rhs the right hand boolean
- * @return EqualsBuilder - used to chain calls.
- */
- public EqualsBuilder append(boolean lhs, boolean rhs) {
- if (isEquals == false) {
- return this;
- }
- isEquals = (lhs == rhs);
- return this;
- }
-
- /**
- * Performs a deep comparison of two Object arrays.
- *
- * This also will be called for the top level of
- * multi-dimensional, ragged, and multi-typed arrays.
- *
- * @param lhs the left hand Object[]
- * @param rhs the right hand Object[]
- * @return EqualsBuilder - used to chain calls.
- */
- public EqualsBuilder append(Object[] lhs, Object[] rhs) {
- if (isEquals == false) {
- return this;
- }
- if (lhs == rhs) {
- return this;
- }
- if (lhs == null || rhs == null) {
- this.setEquals(false);
- return this;
- }
- if (lhs.length != rhs.length) {
- this.setEquals(false);
- return this;
- }
- for (int i = 0; i < lhs.length && isEquals; ++i) {
- append(lhs[i], rhs[i]);
- }
- return this;
- }
-
- /**
- * Deep comparison of array of long. Length and all
- * values are compared.
- *
- * The method {@link #append(long, long)} is used.
- *
- * @param lhs the left hand long[]
- * @param rhs the right hand long[]
- * @return EqualsBuilder - used to chain calls.
- */
- public EqualsBuilder append(long[] lhs, long[] rhs) {
- if (isEquals == false) {
- return this;
- }
- if (lhs == rhs) {
- return this;
- }
- if (lhs == null || rhs == null) {
- this.setEquals(false);
- return this;
- }
- if (lhs.length != rhs.length) {
- this.setEquals(false);
- return this;
- }
- for (int i = 0; i < lhs.length && isEquals; ++i) {
- append(lhs[i], rhs[i]);
- }
- return this;
- }
-
- /**
- * Deep comparison of array of int. Length and all
- * values are compared.
- *
- * The method {@link #append(int, int)} is used.
- *
- * @param lhs the left hand int[]
- * @param rhs the right hand int[]
- * @return EqualsBuilder - used to chain calls.
- */
- public EqualsBuilder append(int[] lhs, int[] rhs) {
- if (isEquals == false) {
- return this;
- }
- if (lhs == rhs) {
- return this;
- }
- if (lhs == null || rhs == null) {
- this.setEquals(false);
- return this;
- }
- if (lhs.length != rhs.length) {
- this.setEquals(false);
- return this;
- }
- for (int i = 0; i < lhs.length && isEquals; ++i) {
- append(lhs[i], rhs[i]);
- }
- return this;
- }
-
- /**
- * Deep comparison of array of short. Length and all
- * values are compared.
- *
- * The method {@link #append(short, short)} is used.
- *
- * @param lhs the left hand short[]
- * @param rhs the right hand short[]
- * @return EqualsBuilder - used to chain calls.
- */
- public EqualsBuilder append(short[] lhs, short[] rhs) {
- if (isEquals == false) {
- return this;
- }
- if (lhs == rhs) {
- return this;
- }
- if (lhs == null || rhs == null) {
- this.setEquals(false);
- return this;
- }
- if (lhs.length != rhs.length) {
- this.setEquals(false);
- return this;
- }
- for (int i = 0; i < lhs.length && isEquals; ++i) {
- append(lhs[i], rhs[i]);
- }
- return this;
- }
-
- /**
- * Deep comparison of array of char. Length and all
- * values are compared.
- *
- * The method {@link #append(char, char)} is used.
- *
- * @param lhs the left hand char[]
- * @param rhs the right hand char[]
- * @return EqualsBuilder - used to chain calls.
- */
- public EqualsBuilder append(char[] lhs, char[] rhs) {
- if (isEquals == false) {
- return this;
- }
- if (lhs == rhs) {
- return this;
- }
- if (lhs == null || rhs == null) {
- this.setEquals(false);
- return this;
- }
- if (lhs.length != rhs.length) {
- this.setEquals(false);
- return this;
- }
- for (int i = 0; i < lhs.length && isEquals; ++i) {
- append(lhs[i], rhs[i]);
- }
- return this;
- }
-
- /**
- * Deep comparison of array of byte. Length and all
- * values are compared.
- *
- * The method {@link #append(byte, byte)} is used.
- *
- * @param lhs the left hand byte[]
- * @param rhs the right hand byte[]
- * @return EqualsBuilder - used to chain calls.
- */
- public EqualsBuilder append(byte[] lhs, byte[] rhs) {
- if (isEquals == false) {
- return this;
- }
- if (lhs == rhs) {
- return this;
- }
- if (lhs == null || rhs == null) {
- this.setEquals(false);
- return this;
- }
- if (lhs.length != rhs.length) {
- this.setEquals(false);
- return this;
- }
- for (int i = 0; i < lhs.length && isEquals; ++i) {
- append(lhs[i], rhs[i]);
- }
- return this;
- }
-
- /**
- * Deep comparison of array of double. Length and all
- * values are compared.
- *
- * The method {@link #append(double, double)} is used.
- *
- * @param lhs the left hand double[]
- * @param rhs the right hand double[]
- * @return EqualsBuilder - used to chain calls.
- */
- public EqualsBuilder append(double[] lhs, double[] rhs) {
- if (isEquals == false) {
- return this;
- }
- if (lhs == rhs) {
- return this;
- }
- if (lhs == null || rhs == null) {
- this.setEquals(false);
- return this;
- }
- if (lhs.length != rhs.length) {
- this.setEquals(false);
- return this;
- }
- for (int i = 0; i < lhs.length && isEquals; ++i) {
- append(lhs[i], rhs[i]);
- }
- return this;
- }
-
- /**
- * Deep comparison of array of float. Length and all
- * values are compared.
- *
- * The method {@link #append(float, float)} is used.
- *
- * @param lhs the left hand float[]
- * @param rhs the right hand float[]
- * @return EqualsBuilder - used to chain calls.
- */
- public EqualsBuilder append(float[] lhs, float[] rhs) {
- if (isEquals == false) {
- return this;
- }
- if (lhs == rhs) {
- return this;
- }
- if (lhs == null || rhs == null) {
- this.setEquals(false);
- return this;
- }
- if (lhs.length != rhs.length) {
- this.setEquals(false);
- return this;
- }
- for (int i = 0; i < lhs.length && isEquals; ++i) {
- append(lhs[i], rhs[i]);
- }
- return this;
- }
-
- /**
- * Deep comparison of array of boolean. Length and all
- * values are compared.
- *
- * The method {@link #append(boolean, boolean)} is used.
- *
- * @param lhs the left hand boolean[]
- * @param rhs the right hand boolean[]
- * @return EqualsBuilder - used to chain calls.
- */
- public EqualsBuilder append(boolean[] lhs, boolean[] rhs) {
- if (isEquals == false) {
- return this;
- }
- if (lhs == rhs) {
- return this;
- }
- if (lhs == null || rhs == null) {
- this.setEquals(false);
- return this;
- }
- if (lhs.length != rhs.length) {
- this.setEquals(false);
- return this;
- }
- for (int i = 0; i < lhs.length && isEquals; ++i) {
- append(lhs[i], rhs[i]);
- }
- return this;
- }
-
- /**
- * Returns true if the fields that have been checked
- * are all equal.
- *
- * @return boolean
- */
- public boolean isEquals() {
- return this.isEquals;
- }
-
- /**
- * Returns true if the fields that have been checked
- * are all equal.
- *
- * @return true if all of the fields that have been checked
- * are equal, false otherwise.
- *
- * @since 3.0
- */
- public Boolean build() {
- return Boolean.valueOf(isEquals());
- }
-
- /**
- * Sets the isEquals value.
- *
- * @param isEquals The value to set.
- * @since 2.1
- */
- protected void setEquals(boolean isEquals) {
- this.isEquals = isEquals;
- }
-
- /**
- * Reset the EqualsBuilder so you can use the same object again
- * @since 2.5
- */
- public void reset() {
- this.isEquals = true;
- }
-}
diff --git a/core/src/main/java/external/org/apache/commons/lang3/builder/HashCodeBuilder.java b/core/src/main/java/external/org/apache/commons/lang3/builder/HashCodeBuilder.java
deleted file mode 100644
index 093a9661..00000000
--- a/core/src/main/java/external/org/apache/commons/lang3/builder/HashCodeBuilder.java
+++ /dev/null
@@ -1,961 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package external.org.apache.commons.lang3.builder;
-
-import java.lang.reflect.AccessibleObject;
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
-
-import external.org.apache.commons.lang3.ArrayUtils;
-
-/**
- *
- * Assists in implementing {@link Object#hashCode()} methods.
- *
- *
- *
- * This class enables a good hashCode method to be built for any class. It follows the rules laid out in
- * the book Effective Java by Joshua Bloch. Writing a
- * good hashCode method is actually quite difficult. This class aims to simplify the process.
- *
- *
- *
- * The following is the approach taken. When appending a data field, the current total is multiplied by the
- * multiplier then a relevant value
- * for that data type is added. For example, if the current hashCode is 17, and the multiplier is 37, then
- * appending the integer 45 will create a hashcode of 674, namely 17 * 37 + 45.
- *
- *
- *
- * All relevant fields from the object should be included in the hashCode method. Derived fields may be
- * excluded. In general, any field used in the equals method must be used in the hashCode
- * method.
- *
- *
- *
- * To use this class write code as follows:
- *
- *
- *
- * public class Person {
- * String name;
- * int age;
- * boolean smoker;
- * ...
- *
- * public int hashCode() {
- * // you pick a hard-coded, randomly chosen, non-zero, odd number
- * // ideally different for each class
- * return new HashCodeBuilder(17, 37).
- * append(name).
- * append(age).
- * append(smoker).
- * toHashCode();
- * }
- * }
- *
- *
- *
- * If required, the superclass hashCode() can be added using {@link #appendSuper}.
- *
- *
- *
- * Alternatively, there is a method that uses reflection to determine the fields to test. Because these fields are
- * usually private, the method, reflectionHashCode, uses AccessibleObject.setAccessible
- * to change the visibility of the fields. This will fail under a security manager, unless the appropriate permissions
- * are set up correctly. It is also slower than testing explicitly.
- *
- *
- *
- * A typical invocation for this method would look like:
- *
- *
- *
- * public int hashCode() {
- * return HashCodeBuilder.reflectionHashCode(this);
- * }
- *
- *
- * @since 1.0
- * @version $Id: HashCodeBuilder.java 1144929 2011-07-10 18:26:16Z ggregory $
- */
-public class HashCodeBuilder implements Builder {
- /**
- *
- * A registry of objects used by reflection methods to detect cyclical object references and avoid infinite loops.
- *
- *
- * @since 2.3
- */
- private static final ThreadLocal> REGISTRY = new ThreadLocal>();
-
- /*
- * NOTE: we cannot store the actual objects in a HashSet, as that would use the very hashCode()
- * we are in the process of calculating.
- *
- * So we generate a one-to-one mapping from the original object to a new object.
- *
- * Now HashSet uses equals() to determine if two elements with the same hashcode really
- * are equal, so we also need to ensure that the replacement objects are only equal
- * if the original objects are identical.
- *
- * The original implementation (2.4 and before) used the System.indentityHashCode()
- * method - however this is not guaranteed to generate unique ids (e.g. LANG-459)
- *
- * We now use the IDKey helper class (adapted from org.apache.axis.utils.IDKey)
- * to disambiguate the duplicate ids.
- */
-
- /**
- *
- * Returns the registry of objects being traversed by the reflection methods in the current thread.
- *
- *
- * @return Set the registry of objects being traversed
- * @since 2.3
- */
- static Set getRegistry() {
- return REGISTRY.get();
- }
-
- /**
- *
- * Returns true if the registry contains the given object. Used by the reflection methods to avoid
- * infinite loops.
- *
- *
- * @param value
- * The object to lookup in the registry.
- * @return boolean true if the registry contains the given object.
- * @since 2.3
- */
- static boolean isRegistered(Object value) {
- Set registry = getRegistry();
- return registry != null && registry.contains(new IDKey(value));
- }
-
- /**
- *
- * Appends the fields and values defined by the given object of the given Class.
- *
- *
- * @param object
- * the object to append details of
- * @param clazz
- * the class to append details of
- * @param builder
- * the builder to append to
- * @param useTransients
- * whether to use transient fields
- * @param excludeFields
- * Collection of String field names to exclude from use in calculation of hash code
- */
- private static void reflectionAppend(Object object, Class> clazz, HashCodeBuilder builder, boolean useTransients,
- String[] excludeFields) {
- if (isRegistered(object)) {
- return;
- }
- try {
- register(object);
- Field[] fields = clazz.getDeclaredFields();
- AccessibleObject.setAccessible(fields, true);
- for (Field field : fields) {
- if (!ArrayUtils.contains(excludeFields, field.getName())
- && (field.getName().indexOf('$') == -1)
- && (useTransients || !Modifier.isTransient(field.getModifiers()))
- && (!Modifier.isStatic(field.getModifiers()))) {
- try {
- Object fieldValue = field.get(object);
- builder.append(fieldValue);
- } catch (IllegalAccessException e) {
- // this can't happen. Would get a Security exception instead
- // throw a runtime exception in case the impossible happens.
- throw new InternalError("Unexpected IllegalAccessException");
- }
- }
- }
- } finally {
- unregister(object);
- }
- }
-
- /**
- *
- * This method uses reflection to build a valid hash code.
- *
- *
- *
- * It uses AccessibleObject.setAccessible to gain access to private fields. This means that it will
- * throw a security exception if run under a security manager, if the permissions are not set up correctly. It is
- * also not as efficient as testing explicitly.
- *
- *
- *
- * Transient members will be not be used, as they are likely derived fields, and not part of the value of the
- * Object.
- *
- *
- *
- * Static fields will not be tested. Superclass fields will be included.
- *
- *
- *
- * Two randomly chosen, non-zero, odd numbers must be passed in. Ideally these should be different for each class,
- * however this is not vital. Prime numbers are preferred, especially for the multiplier.
- *
- *
- * @param initialNonZeroOddNumber
- * a non-zero, odd number used as the initial value
- * @param multiplierNonZeroOddNumber
- * a non-zero, odd number used as the multiplier
- * @param object
- * the Object to create a hashCode for
- * @return int hash code
- * @throws IllegalArgumentException
- * if the Object is null
- * @throws IllegalArgumentException
- * if the number is zero or even
- */
- public static int reflectionHashCode(int initialNonZeroOddNumber, int multiplierNonZeroOddNumber, Object object) {
- return reflectionHashCode(initialNonZeroOddNumber, multiplierNonZeroOddNumber, object, false, null);
- }
-
- /**
- *
- * This method uses reflection to build a valid hash code.
- *
- *
- *
- * It uses AccessibleObject.setAccessible to gain access to private fields. This means that it will
- * throw a security exception if run under a security manager, if the permissions are not set up correctly. It is
- * also not as efficient as testing explicitly.
- *
- *
- *
- * If the TestTransients parameter is set to true, transient members will be tested, otherwise they
- * are ignored, as they are likely derived fields, and not part of the value of the Object.
- *
- *
- *
- * Static fields will not be tested. Superclass fields will be included.
- *
- *
- *
- * Two randomly chosen, non-zero, odd numbers must be passed in. Ideally these should be different for each class,
- * however this is not vital. Prime numbers are preferred, especially for the multiplier.
- *
- *
- * @param initialNonZeroOddNumber
- * a non-zero, odd number used as the initial value
- * @param multiplierNonZeroOddNumber
- * a non-zero, odd number used as the multiplier
- * @param object
- * the Object to create a hashCode for
- * @param testTransients
- * whether to include transient fields
- * @return int hash code
- * @throws IllegalArgumentException
- * if the Object is null
- * @throws IllegalArgumentException
- * if the number is zero or even
- */
- public static int reflectionHashCode(int initialNonZeroOddNumber, int multiplierNonZeroOddNumber, Object object,
- boolean testTransients) {
- return reflectionHashCode(initialNonZeroOddNumber, multiplierNonZeroOddNumber, object, testTransients, null);
- }
-
- /**
- *
- * This method uses reflection to build a valid hash code.
- *
- *
- *
- * It uses AccessibleObject.setAccessible to gain access to private fields. This means that it will
- * throw a security exception if run under a security manager, if the permissions are not set up correctly. It is
- * also not as efficient as testing explicitly.
- *
- *
- *
- * If the TestTransients parameter is set to true, transient members will be tested, otherwise they
- * are ignored, as they are likely derived fields, and not part of the value of the Object.
- *
- *
- *
- * Static fields will not be included. Superclass fields will be included up to and including the specified
- * superclass. A null superclass is treated as java.lang.Object.
- *
- *
- *
- * Two randomly chosen, non-zero, odd numbers must be passed in. Ideally these should be different for each class,
- * however this is not vital. Prime numbers are preferred, especially for the multiplier.
- *
- *
- * @param
- * the type of the object involved
- * @param initialNonZeroOddNumber
- * a non-zero, odd number used as the initial value
- * @param multiplierNonZeroOddNumber
- * a non-zero, odd number used as the multiplier
- * @param object
- * the Object to create a hashCode for
- * @param testTransients
- * whether to include transient fields
- * @param reflectUpToClass
- * the superclass to reflect up to (inclusive), may be null
- * @param excludeFields
- * array of field names to exclude from use in calculation of hash code
- * @return int hash code
- * @throws IllegalArgumentException
- * if the Object is null
- * @throws IllegalArgumentException
- * if the number is zero or even
- * @since 2.0
- */
- public static int reflectionHashCode(int initialNonZeroOddNumber, int multiplierNonZeroOddNumber, T object,
- boolean testTransients, Class super T> reflectUpToClass, String... excludeFields) {
-
- if (object == null) {
- throw new IllegalArgumentException("The object to build a hash code for must not be null");
- }
- HashCodeBuilder builder = new HashCodeBuilder(initialNonZeroOddNumber, multiplierNonZeroOddNumber);
- Class> clazz = object.getClass();
- reflectionAppend(object, clazz, builder, testTransients, excludeFields);
- while (clazz.getSuperclass() != null && clazz != reflectUpToClass) {
- clazz = clazz.getSuperclass();
- reflectionAppend(object, clazz, builder, testTransients, excludeFields);
- }
- return builder.toHashCode();
- }
-
- /**
- *
- * This method uses reflection to build a valid hash code.
- *
- *
- *
- * This constructor uses two hard coded choices for the constants needed to build a hash code.
- *
- *
- *
- * It uses AccessibleObject.setAccessible to gain access to private fields. This means that it will
- * throw a security exception if run under a security manager, if the permissions are not set up correctly. It is
- * also not as efficient as testing explicitly.
- *
- *
- *
- * If the TestTransients parameter is set to true, transient members will be tested, otherwise they
- * are ignored, as they are likely derived fields, and not part of the value of the Object.
- *
- *
- *
- * Static fields will not be tested. Superclass fields will be included.
- *
- *
- * @param object
- * the Object to create a hashCode for
- * @param testTransients
- * whether to include transient fields
- * @return int hash code
- * @throws IllegalArgumentException
- * if the object is null
- */
- public static int reflectionHashCode(Object object, boolean testTransients) {
- return reflectionHashCode(17, 37, object, testTransients, null);
- }
-
- /**
- *
- * This method uses reflection to build a valid hash code.
- *
- *
- *
- * This constructor uses two hard coded choices for the constants needed to build a hash code.
- *
- *
- *
- * It uses AccessibleObject.setAccessible to gain access to private fields. This means that it will
- * throw a security exception if run under a security manager, if the permissions are not set up correctly. It is
- * also not as efficient as testing explicitly.
- *
- *
- *
- * Transient members will be not be used, as they are likely derived fields, and not part of the value of the
- * Object.
- *
- *
- *
- * Static fields will not be tested. Superclass fields will be included.
- *
- *
- * @param object
- * the Object to create a hashCode for
- * @param excludeFields
- * Collection of String field names to exclude from use in calculation of hash code
- * @return int hash code
- * @throws IllegalArgumentException
- * if the object is null
- */
- public static int reflectionHashCode(Object object, Collection excludeFields) {
- return reflectionHashCode(object, ReflectionToStringBuilder.toNoNullStringArray(excludeFields));
- }
-
- // -------------------------------------------------------------------------
-
- /**
- *
- * This method uses reflection to build a valid hash code.
- *
- *
- *
- * This constructor uses two hard coded choices for the constants needed to build a hash code.
- *
- *
- *
- * It uses AccessibleObject.setAccessible to gain access to private fields. This means that it will
- * throw a security exception if run under a security manager, if the permissions are not set up correctly. It is
- * also not as efficient as testing explicitly.
- *
- *
- *
- * Transient members will be not be used, as they are likely derived fields, and not part of the value of the
- * Object.
- *
- *
- *
- * Static fields will not be tested. Superclass fields will be included.
- *
- *
- * @param object
- * the Object to create a hashCode for
- * @param excludeFields
- * array of field names to exclude from use in calculation of hash code
- * @return int hash code
- * @throws IllegalArgumentException
- * if the object is null
- */
- public static int reflectionHashCode(Object object, String... excludeFields) {
- return reflectionHashCode(17, 37, object, false, null, excludeFields);
- }
-
- /**
- *
- * Registers the given object. Used by the reflection methods to avoid infinite loops.
- *
- *
- * @param value
- * The object to register.
- */
- static void register(Object value) {
- synchronized (HashCodeBuilder.class) {
- if (getRegistry() == null) {
- REGISTRY.set(new HashSet());
- }
- }
- getRegistry().add(new IDKey(value));
- }
-
- /**
- *
- * Unregisters the given object.
- *
- *
- *
- * Used by the reflection methods to avoid infinite loops.
- *
- * @param value
- * The object to unregister.
- * @since 2.3
- */
- static void unregister(Object value) {
- Set registry = getRegistry();
- if (registry != null) {
- registry.remove(new IDKey(value));
- synchronized (HashCodeBuilder.class) {
- //read again
- registry = getRegistry();
- if (registry != null && registry.isEmpty()) {
- REGISTRY.remove();
- }
- }
- }
- }
-
- /**
- * Constant to use in building the hashCode.
- */
- private final int iConstant;
-
- /**
- * Running total of the hashCode.
- */
- private int iTotal = 0;
-
- /**
- *
- * Uses two hard coded choices for the constants needed to build a hashCode.
- *
- */
- public HashCodeBuilder() {
- iConstant = 37;
- iTotal = 17;
- }
-
- /**
- *
- * Two randomly chosen, non-zero, odd numbers must be passed in. Ideally these should be different for each class,
- * however this is not vital.
- *
- *
- *
- * Prime numbers are preferred, especially for the multiplier.
- *
- *
- * @param initialNonZeroOddNumber
- * a non-zero, odd number used as the initial value
- * @param multiplierNonZeroOddNumber
- * a non-zero, odd number used as the multiplier
- * @throws IllegalArgumentException
- * if the number is zero or even
- */
- public HashCodeBuilder(int initialNonZeroOddNumber, int multiplierNonZeroOddNumber) {
- if (initialNonZeroOddNumber == 0) {
- throw new IllegalArgumentException("HashCodeBuilder requires a non zero initial value");
- }
- if (initialNonZeroOddNumber % 2 == 0) {
- throw new IllegalArgumentException("HashCodeBuilder requires an odd initial value");
- }
- if (multiplierNonZeroOddNumber == 0) {
- throw new IllegalArgumentException("HashCodeBuilder requires a non zero multiplier");
- }
- if (multiplierNonZeroOddNumber % 2 == 0) {
- throw new IllegalArgumentException("HashCodeBuilder requires an odd multiplier");
- }
- iConstant = multiplierNonZeroOddNumber;
- iTotal = initialNonZeroOddNumber;
- }
-
- /**
- *
- * Append a hashCode for a boolean.
- *
- *
- * This adds 1 when true, and 0 when false to the hashCode.
- *
- *
- * This is in contrast to the standard java.lang.Boolean.hashCode handling, which computes
- * a hashCode value of 1231 for java.lang.Boolean instances
- * that represent true or 1237 for java.lang.Boolean instances
- * that represent false.
- *
- *
- * This is in accordance with the Effective Java
design.
- *
- *
- * @param value
- * the boolean to add to the hashCode
- * @return this
- */
- public HashCodeBuilder append(boolean value) {
- iTotal = iTotal * iConstant + (value ? 0 : 1);
- return this;
- }
-
- /**
- *
- * Append a hashCode for a boolean array.
- *
- *
- * @param array
- * the array to add to the hashCode
- * @return this
- */
- public HashCodeBuilder append(boolean[] array) {
- if (array == null) {
- iTotal = iTotal * iConstant;
- } else {
- for (boolean element : array) {
- append(element);
- }
- }
- return this;
- }
-
- // -------------------------------------------------------------------------
-
- /**
- *
- * Append a hashCode for a byte.
- *
- *
- * @param value
- * the byte to add to the hashCode
- * @return this
- */
- public HashCodeBuilder append(byte value) {
- iTotal = iTotal * iConstant + value;
- return this;
- }
-
- // -------------------------------------------------------------------------
-
- /**
- *
- * Append a hashCode for a byte array.
- *
- *
- * @param array
- * the array to add to the hashCode
- * @return this
- */
- public HashCodeBuilder append(byte[] array) {
- if (array == null) {
- iTotal = iTotal * iConstant;
- } else {
- for (byte element : array) {
- append(element);
- }
- }
- return this;
- }
-
- /**
- *
- * Append a hashCode for a char.
- *
- *
- * @param value
- * the char to add to the hashCode
- * @return this
- */
- public HashCodeBuilder append(char value) {
- iTotal = iTotal * iConstant + value;
- return this;
- }
-
- /**
- *
- * Append a hashCode for a char array.
- *
- *
- * @param array
- * the array to add to the hashCode
- * @return this
- */
- public HashCodeBuilder append(char[] array) {
- if (array == null) {
- iTotal = iTotal * iConstant;
- } else {
- for (char element : array) {
- append(element);
- }
- }
- return this;
- }
-
- /**
- *
- * Append a hashCode for a double.
- *
- *
- * @param value
- * the double to add to the hashCode
- * @return this
- */
- public HashCodeBuilder append(double value) {
- return append(Double.doubleToLongBits(value));
- }
-
- /**
- *
- * Append a hashCode for a double array.
- *
- *
- * @param array
- * the array to add to the hashCode
- * @return this
- */
- public HashCodeBuilder append(double[] array) {
- if (array == null) {
- iTotal = iTotal * iConstant;
- } else {
- for (double element : array) {
- append(element);
- }
- }
- return this;
- }
-
- /**
- *
- * Append a hashCode for a float.
- *
- *
- * @param value
- * the float to add to the hashCode
- * @return this
- */
- public HashCodeBuilder append(float value) {
- iTotal = iTotal * iConstant + Float.floatToIntBits(value);
- return this;
- }
-
- /**
- *
- * Append a hashCode for a float array.
- *
- *
- * @param array
- * the array to add to the hashCode
- * @return this
- */
- public HashCodeBuilder append(float[] array) {
- if (array == null) {
- iTotal = iTotal * iConstant;
- } else {
- for (float element : array) {
- append(element);
- }
- }
- return this;
- }
-
- /**
- *
- * Append a hashCode for an int.
- *
- *
- * @param value
- * the int to add to the hashCode
- * @return this
- */
- public HashCodeBuilder append(int value) {
- iTotal = iTotal * iConstant + value;
- return this;
- }
-
- /**
- *
- * Append a hashCode for an int array.
- *
- *
- * @param array
- * the array to add to the hashCode
- * @return this
- */
- public HashCodeBuilder append(int[] array) {
- if (array == null) {
- iTotal = iTotal * iConstant;
- } else {
- for (int element : array) {
- append(element);
- }
- }
- return this;
- }
-
- /**
- *
- * Append a hashCode for a long.
- *
- *
- * @param value
- * the long to add to the hashCode
- * @return this
- */
- // NOTE: This method uses >> and not >>> as Effective Java and
- // Long.hashCode do. Ideally we should switch to >>> at
- // some stage. There are backwards compat issues, so
- // that will have to wait for the time being. cf LANG-342.
- public HashCodeBuilder append(long value) {
- iTotal = iTotal * iConstant + ((int) (value ^ (value >> 32)));
- return this;
- }
-
- /**
- *
- * Append a hashCode for a long array.
- *
- *
- * @param array
- * the array to add to the hashCode
- * @return this
- */
- public HashCodeBuilder append(long[] array) {
- if (array == null) {
- iTotal = iTotal * iConstant;
- } else {
- for (long element : array) {
- append(element);
- }
- }
- return this;
- }
-
- /**
- *
- * Append a hashCode for an Object.
- *
- *
- * @param object
- * the Object to add to the hashCode
- * @return this
- */
- public HashCodeBuilder append(Object object) {
- if (object == null) {
- iTotal = iTotal * iConstant;
-
- } else {
- if(object.getClass().isArray()) {
- // 'Switch' on type of array, to dispatch to the correct handler
- // This handles multi dimensional arrays
- if (object instanceof long[]) {
- append((long[]) object);
- } else if (object instanceof int[]) {
- append((int[]) object);
- } else if (object instanceof short[]) {
- append((short[]) object);
- } else if (object instanceof char[]) {
- append((char[]) object);
- } else if (object instanceof byte[]) {
- append((byte[]) object);
- } else if (object instanceof double[]) {
- append((double[]) object);
- } else if (object instanceof float[]) {
- append((float[]) object);
- } else if (object instanceof boolean[]) {
- append((boolean[]) object);
- } else {
- // Not an array of primitives
- append((Object[]) object);
- }
- } else {
- iTotal = iTotal * iConstant + object.hashCode();
- }
- }
- return this;
- }
-
- /**
- *
- * Append a hashCode for an Object array.
- *
- *
- * @param array
- * the array to add to the hashCode
- * @return this
- */
- public HashCodeBuilder append(Object[] array) {
- if (array == null) {
- iTotal = iTotal * iConstant;
- } else {
- for (Object element : array) {
- append(element);
- }
- }
- return this;
- }
-
- /**
- *
- * Append a hashCode for a short.
- *
- *
- * @param value
- * the short to add to the hashCode
- * @return this
- */
- public HashCodeBuilder append(short value) {
- iTotal = iTotal * iConstant + value;
- return this;
- }
-
- /**
- *
- * Append a hashCode for a short array.
- *
- *
- * @param array
- * the array to add to the hashCode
- * @return this
- */
- public HashCodeBuilder append(short[] array) {
- if (array == null) {
- iTotal = iTotal * iConstant;
- } else {
- for (short element : array) {
- append(element);
- }
- }
- return this;
- }
-
- /**
- *
- * Adds the result of super.hashCode() to this builder.
- *
- *
- * @param superHashCode
- * the result of calling super.hashCode()
- * @return this HashCodeBuilder, used to chain calls.
- * @since 2.0
- */
- public HashCodeBuilder appendSuper(int superHashCode) {
- iTotal = iTotal * iConstant + superHashCode;
- return this;
- }
-
- /**
- *
- * Return the computed hashCode.
- *
- *
- * @return hashCode based on the fields appended
- */
- public int toHashCode() {
- return iTotal;
- }
-
- /**
- * Returns the computed hashCode.
- *
- * @return hashCode based on the fields appended
- *
- * @since 3.0
- */
- public Integer build() {
- return Integer.valueOf(toHashCode());
- }
-
- /**
- *
- * The computed hashCode from toHashCode() is returned due to the likelihood
- * of bugs in mis-calling toHashCode() and the unlikeliness of it mattering what the hashCode for
- * HashCodeBuilder itself is.
- *
- * @return hashCode based on the fields appended
- * @since 2.5
- */
- @Override
- public int hashCode() {
- return toHashCode();
- }
-
-}
diff --git a/core/src/main/java/external/org/apache/commons/lang3/builder/IDKey.java b/core/src/main/java/external/org/apache/commons/lang3/builder/IDKey.java
deleted file mode 100644
index 68d93885..00000000
--- a/core/src/main/java/external/org/apache/commons/lang3/builder/IDKey.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package external.org.apache.commons.lang3.builder;
-
-// adapted from org.apache.axis.utils.IDKey
-
-/**
- * Wrap an identity key (System.identityHashCode())
- * so that an object can only be equal() to itself.
- *
- * This is necessary to disambiguate the occasional duplicate
- * identityHashCodes that can occur.
- *
- */
-final class IDKey {
- private final Object value;
- private final int id;
-
- /**
- * Constructor for IDKey
- * @param _value The value
- */
- public IDKey(Object _value) {
- // This is the Object hashcode
- id = System.identityHashCode(_value);
- // There have been some cases (LANG-459) that return the
- // same identity hash code for different objects. So
- // the value is also added to disambiguate these cases.
- value = _value;
- }
-
- /**
- * returns hashcode - i.e. the system identity hashcode.
- * @return the hashcode
- */
- @Override
- public int hashCode() {
- return id;
- }
-
- /**
- * checks if instances are equal
- * @param other The other object to compare to
- * @return if the instances are for the same object
- */
- @Override
- public boolean equals(Object other) {
- if (!(other instanceof IDKey)) {
- return false;
- }
- IDKey idKey = (IDKey) other;
- if (id != idKey.id) {
- return false;
- }
- // Note that identity equals is used.
- return value == idKey.value;
- }
-}
diff --git a/core/src/main/java/external/org/apache/commons/lang3/builder/ReflectionToStringBuilder.java b/core/src/main/java/external/org/apache/commons/lang3/builder/ReflectionToStringBuilder.java
deleted file mode 100644
index a6f41ec6..00000000
--- a/core/src/main/java/external/org/apache/commons/lang3/builder/ReflectionToStringBuilder.java
+++ /dev/null
@@ -1,691 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package external.org.apache.commons.lang3.builder;
-
-import java.lang.reflect.AccessibleObject;
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-
-import external.org.apache.commons.lang3.ArrayUtils;
-import external.org.apache.commons.lang3.ClassUtils;
-
-/**
- *
- * Assists in implementing {@link Object#toString()} methods using reflection.
- *
- *
- * This class uses reflection to determine the fields to append. Because these fields are usually private, the class
- * uses {@link java.lang.reflect.AccessibleObject#setAccessible(java.lang.reflect.AccessibleObject[], boolean)} to
- * change the visibility of the fields. This will fail under a security manager, unless the appropriate permissions are
- * set up correctly.
- *
- *
- * Using reflection to access (private) fields circumvents any synchronization protection guarding access to these
- * fields. If a toString method cannot safely read a field, you should exclude it from the toString method, or use
- * synchronization consistent with the class' lock management around the invocation of the method. Take special care to
- * exclude non-thread-safe collection classes, because these classes may throw ConcurrentModificationException if
- * modified while the toString method is executing.
- *
- *
- * A typical invocation for this method would look like:
- *
- *
- * public String toString() {
- * return ReflectionToStringBuilder.toString(this);
- * }
- *
- *
- * You can also use the builder to debug 3rd party objects:
- *
- *
- * System.out.println("An object: " + ReflectionToStringBuilder.toString(anObject));
- *
- *
- * A subclass can control field output by overriding the methods:
- *
- * {@link #accept(java.lang.reflect.Field)}
- * {@link #getValue(java.lang.reflect.Field)}
- *
- *
- *
- * For example, this method does not include the password field in the returned String:
- *
- *
- * public String toString() {
- * return (new ReflectionToStringBuilder(this) {
- * protected boolean accept(Field f) {
- * return super.accept(f) && !f.getName().equals("password");
- * }
- * }).toString();
- * }
- *
- *
- * The exact format of the toString is determined by the {@link ToStringStyle} passed into the constructor.
- *
- *
- * @since 2.0
- * @version $Id: ReflectionToStringBuilder.java 1200177 2011-11-10 06:14:33Z ggregory $
- */
-public class ReflectionToStringBuilder extends ToStringBuilder {
-
- /**
- *
- * Builds a toString value using the default ToStringStyle through reflection.
- *
- *
- *
- * It uses AccessibleObject.setAccessible to gain access to private fields. This means that it will
- * throw a security exception if run under a security manager, if the permissions are not set up correctly. It is
- * also not as efficient as testing explicitly.
- *
- *
- *
- * Transient members will be not be included, as they are likely derived. Static fields will not be included.
- * Superclass fields will be appended.
- *
- *
- * @param object
- * the Object to be output
- * @return the String result
- * @throws IllegalArgumentException
- * if the Object is null
- */
- public static String toString(Object object) {
- return toString(object, null, false, false, null);
- }
-
- /**
- *
- * Builds a toString value through reflection.
- *
- *
- *
- * It uses AccessibleObject.setAccessible to gain access to private fields. This means that it will
- * throw a security exception if run under a security manager, if the permissions are not set up correctly. It is
- * also not as efficient as testing explicitly.
- *
- *
- *
- * Transient members will be not be included, as they are likely derived. Static fields will not be included.
- * Superclass fields will be appended.
- *
- *
- *
- * If the style is null, the default ToStringStyle is used.
- *
- *
- * @param object
- * the Object to be output
- * @param style
- * the style of the toString to create, may be null
- * @return the String result
- * @throws IllegalArgumentException
- * if the Object or ToStringStyle is null
- */
- public static String toString(Object object, ToStringStyle style) {
- return toString(object, style, false, false, null);
- }
-
- /**
- *
- * Builds a toString value through reflection.
- *
- *
- *
- * It uses AccessibleObject.setAccessible to gain access to private fields. This means that it will
- * throw a security exception if run under a security manager, if the permissions are not set up correctly. It is
- * also not as efficient as testing explicitly.
- *
- *
- *
- * If the outputTransients is true, transient members will be output, otherwise they
- * are ignored, as they are likely derived fields, and not part of the value of the Object.
- *
- *
- *
- * Static fields will not be included. Superclass fields will be appended.
- *
- *
- *
- * If the style is null, the default ToStringStyle is used.
- *
- *
- * @param object
- * the Object to be output
- * @param style
- * the style of the toString to create, may be null
- * @param outputTransients
- * whether to include transient fields
- * @return the String result
- * @throws IllegalArgumentException
- * if the Object is null
- */
- public static String toString(Object object, ToStringStyle style, boolean outputTransients) {
- return toString(object, style, outputTransients, false, null);
- }
-
- /**
- *
- * Builds a toString value through reflection.
- *
- *
- *
- * It uses AccessibleObject.setAccessible to gain access to private fields. This means that it will
- * throw a security exception if run under a security manager, if the permissions are not set up correctly. It is
- * also not as efficient as testing explicitly.
- *
- *
- *
- * If the outputTransients is true, transient fields will be output, otherwise they
- * are ignored, as they are likely derived fields, and not part of the value of the Object.
- *
- *
- *
- * If the outputStatics is true, static fields will be output, otherwise they are
- * ignored.
- *
- *
- *
- * Static fields will not be included. Superclass fields will be appended.
- *
- *
- *
- * If the style is null, the default ToStringStyle is used.
- *
- *
- * @param object
- * the Object to be output
- * @param style
- * the style of the toString to create, may be null
- * @param outputTransients
- * whether to include transient fields
- * @param outputStatics
- * whether to include transient fields
- * @return the String result
- * @throws IllegalArgumentException
- * if the Object is null
- * @since 2.1
- */
- public static String toString(Object object, ToStringStyle style, boolean outputTransients, boolean outputStatics) {
- return toString(object, style, outputTransients, outputStatics, null);
- }
-
- /**
- *
- * Builds a toString value through reflection.
- *
- *
- *
- * It uses AccessibleObject.setAccessible to gain access to private fields. This means that it will
- * throw a security exception if run under a security manager, if the permissions are not set up correctly. It is
- * also not as efficient as testing explicitly.
- *
- *
- *
- * If the outputTransients is true, transient fields will be output, otherwise they
- * are ignored, as they are likely derived fields, and not part of the value of the Object.
- *
- *
- *
- * If the outputStatics is true, static fields will be output, otherwise they are
- * ignored.
- *
- *
- *
- * Superclass fields will be appended up to and including the specified superclass. A null superclass is treated as
- * java.lang.Object.
- *
- *
- *
- * If the style is null, the default ToStringStyle is used.
- *
- *
- * @param
- * the type of the object
- * @param object
- * the Object to be output
- * @param style
- * the style of the toString to create, may be null
- * @param outputTransients
- * whether to include transient fields
- * @param outputStatics
- * whether to include static fields
- * @param reflectUpToClass
- * the superclass to reflect up to (inclusive), may be null
- * @return the String result
- * @throws IllegalArgumentException
- * if the Object is null
- * @since 2.1
- */
- public static String toString(
- T object, ToStringStyle style, boolean outputTransients,
- boolean outputStatics, Class super T> reflectUpToClass) {
- return new ReflectionToStringBuilder(object, style, null, reflectUpToClass, outputTransients, outputStatics)
- .toString();
- }
-
- /**
- * Builds a String for a toString method excluding the given field names.
- *
- * @param object
- * The object to "toString".
- * @param excludeFieldNames
- * The field names to exclude. Null excludes nothing.
- * @return The toString value.
- */
- public static String toStringExclude(Object object, Collection excludeFieldNames) {
- return toStringExclude(object, toNoNullStringArray(excludeFieldNames));
- }
-
- /**
- * Converts the given Collection into an array of Strings. The returned array does not contain null
- * entries. Note that {@link Arrays#sort(Object[])} will throw an {@link NullPointerException} if an array element
- * is null.
- *
- * @param collection
- * The collection to convert
- * @return A new array of Strings.
- */
- static String[] toNoNullStringArray(Collection collection) {
- if (collection == null) {
- return ArrayUtils.EMPTY_STRING_ARRAY;
- }
- return toNoNullStringArray(collection.toArray());
- }
-
- /**
- * Returns a new array of Strings without null elements. Internal method used to normalize exclude lists
- * (arrays and collections). Note that {@link Arrays#sort(Object[])} will throw an {@link NullPointerException}
- * if an array element is null.
- *
- * @param array
- * The array to check
- * @return The given array or a new array without null.
- */
- static String[] toNoNullStringArray(Object[] array) {
- List list = new ArrayList(array.length);
- for (Object e : array) {
- if (e != null) {
- list.add(e.toString());
- }
- }
- return list.toArray(ArrayUtils.EMPTY_STRING_ARRAY);
- }
-
-
- /**
- * Builds a String for a toString method excluding the given field names.
- *
- * @param object
- * The object to "toString".
- * @param excludeFieldNames
- * The field names to exclude
- * @return The toString value.
- */
- public static String toStringExclude(Object object, String... excludeFieldNames) {
- return new ReflectionToStringBuilder(object).setExcludeFieldNames(excludeFieldNames).toString();
- }
-
- /**
- * Whether or not to append static fields.
- */
- private boolean appendStatics = false;
-
- /**
- * Whether or not to append transient fields.
- */
- private boolean appendTransients = false;
-
- /**
- * Which field names to exclude from output. Intended for fields like "password".
- *
- * @since 3.0 this is protected instead of private
- */
- protected String[] excludeFieldNames;
-
- /**
- * The last super class to stop appending fields for.
- */
- private Class> upToClass = null;
-
- /**
- *
- * Constructor.
- *
- *
- *
- * This constructor outputs using the default style set with setDefaultStyle.
- *
- *
- * @param object
- * the Object to build a toString for, must not be null
- * @throws IllegalArgumentException
- * if the Object passed in is null
- */
- public ReflectionToStringBuilder(Object object) {
- super(object);
- }
-
- /**
- *
- * Constructor.
- *
- *
- *
- * If the style is null, the default style is used.
- *
- *
- * @param object
- * the Object to build a toString for, must not be null
- * @param style
- * the style of the toString to create, may be null
- * @throws IllegalArgumentException
- * if the Object passed in is null
- */
- public ReflectionToStringBuilder(Object object, ToStringStyle style) {
- super(object, style);
- }
-
- /**
- *
- * Constructor.
- *
- *
- *
- * If the style is null, the default style is used.
- *
- *
- *
- * If the buffer is null, a new one is created.
- *
- *
- * @param object
- * the Object to build a toString for
- * @param style
- * the style of the toString to create, may be null
- * @param buffer
- * the StringBuffer to populate, may be null
- * @throws IllegalArgumentException
- * if the Object passed in is null
- */
- public ReflectionToStringBuilder(Object object, ToStringStyle style, StringBuffer buffer) {
- super(object, style, buffer);
- }
-
- /**
- * Constructor.
- *
- * @param
- * the type of the object
- * @param object
- * the Object to build a toString for
- * @param style
- * the style of the toString to create, may be null
- * @param buffer
- * the StringBuffer to populate, may be null
- * @param reflectUpToClass
- * the superclass to reflect up to (inclusive), may be null
- * @param outputTransients
- * whether to include transient fields
- * @param outputStatics
- * whether to include static fields
- * @since 2.1
- */
- public ReflectionToStringBuilder(
- T object, ToStringStyle style, StringBuffer buffer,
- Class super T> reflectUpToClass, boolean outputTransients, boolean outputStatics) {
- super(object, style, buffer);
- this.setUpToClass(reflectUpToClass);
- this.setAppendTransients(outputTransients);
- this.setAppendStatics(outputStatics);
- }
-
- /**
- * Returns whether or not to append the given Field.
- *
- * Transient fields are appended only if {@link #isAppendTransients()} returns true.
- * Static fields are appended only if {@link #isAppendStatics()} returns true.
- * Inner class fields are not appened.
- *
- *
- * @param field
- * The Field to test.
- * @return Whether or not to append the given Field.
- */
- protected boolean accept(Field field) {
- if (field.getName().indexOf(ClassUtils.INNER_CLASS_SEPARATOR_CHAR) != -1) {
- // Reject field from inner class.
- return false;
- }
- if (Modifier.isTransient(field.getModifiers()) && !this.isAppendTransients()) {
- // Reject transient fields.
- return false;
- }
- if (Modifier.isStatic(field.getModifiers()) && !this.isAppendStatics()) {
- // Reject static fields.
- return false;
- }
- if (this.excludeFieldNames != null
- && Arrays.binarySearch(this.excludeFieldNames, field.getName()) >= 0) {
- // Reject fields from the getExcludeFieldNames list.
- return false;
- }
- return true;
- }
-
- /**
- *
- * Appends the fields and values defined by the given object of the given Class.
- *
- *
- *
- * If a cycle is detected as an object is "toString()'ed", such an object is rendered as if
- * Object.toString() had been called and not implemented by the object.
- *
- *
- * @param clazz
- * The class of object parameter
- */
- protected void appendFieldsIn(Class> clazz) {
- if (clazz.isArray()) {
- this.reflectionAppendArray(this.getObject());
- return;
- }
- Field[] fields = clazz.getDeclaredFields();
- AccessibleObject.setAccessible(fields, true);
- for (Field field : fields) {
- String fieldName = field.getName();
- if (this.accept(field)) {
- try {
- // Warning: Field.get(Object) creates wrappers objects
- // for primitive types.
- Object fieldValue = this.getValue(field);
- this.append(fieldName, fieldValue);
- } catch (IllegalAccessException ex) {
- //this can't happen. Would get a Security exception
- // instead
- //throw a runtime exception in case the impossible
- // happens.
- throw new InternalError("Unexpected IllegalAccessException: " + ex.getMessage());
- }
- }
- }
- }
-
- /**
- * @return Returns the excludeFieldNames.
- */
- public String[] getExcludeFieldNames() {
- return this.excludeFieldNames.clone();
- }
-
- /**
- *
- * Gets the last super class to stop appending fields for.
- *
- *
- * @return The last super class to stop appending fields for.
- */
- public Class> getUpToClass() {
- return this.upToClass;
- }
-
- /**
- *
- * Calls java.lang.reflect.Field.get(Object).
- *
- *
- * @param field
- * The Field to query.
- * @return The Object from the given Field.
- *
- * @throws IllegalArgumentException
- * see {@link java.lang.reflect.Field#get(Object)}
- * @throws IllegalAccessException
- * see {@link java.lang.reflect.Field#get(Object)}
- *
- * @see java.lang.reflect.Field#get(Object)
- */
- protected Object getValue(Field field) throws IllegalArgumentException, IllegalAccessException {
- return field.get(this.getObject());
- }
-
- /**
- *
- * Gets whether or not to append static fields.
- *
- *
- * @return Whether or not to append static fields.
- * @since 2.1
- */
- public boolean isAppendStatics() {
- return this.appendStatics;
- }
-
- /**
- *
- * Gets whether or not to append transient fields.
- *
- *
- * @return Whether or not to append transient fields.
- */
- public boolean isAppendTransients() {
- return this.appendTransients;
- }
-
- /**
- *
- * Append to the toString an Object array.
- *
- *
- * @param array
- * the array to add to the toString
- * @return this
- */
- public ReflectionToStringBuilder reflectionAppendArray(Object array) {
- this.getStyle().reflectionAppendArrayDetail(this.getStringBuffer(), null, array);
- return this;
- }
-
- /**
- *
- * Sets whether or not to append static fields.
- *
- *
- * @param appendStatics
- * Whether or not to append static fields.
- * @since 2.1
- */
- public void setAppendStatics(boolean appendStatics) {
- this.appendStatics = appendStatics;
- }
-
- /**
- *
- * Sets whether or not to append transient fields.
- *
- *
- * @param appendTransients
- * Whether or not to append transient fields.
- */
- public void setAppendTransients(boolean appendTransients) {
- this.appendTransients = appendTransients;
- }
-
- /**
- * Sets the field names to exclude.
- *
- * @param excludeFieldNamesParam
- * The excludeFieldNames to excluding from toString or null.
- * @return this
- */
- public ReflectionToStringBuilder setExcludeFieldNames(String... excludeFieldNamesParam) {
- if (excludeFieldNamesParam == null) {
- this.excludeFieldNames = null;
- } else {
- //clone and remove nulls
- this.excludeFieldNames = toNoNullStringArray(excludeFieldNamesParam);
- Arrays.sort(this.excludeFieldNames);
- }
- return this;
- }
-
- /**
- *
- * Sets the last super class to stop appending fields for.
- *
- *
- * @param clazz
- * The last super class to stop appending fields for.
- */
- public void setUpToClass(Class> clazz) {
- if (clazz != null) {
- Object object = getObject();
- if (object != null && clazz.isInstance(object) == false) {
- throw new IllegalArgumentException("Specified class is not a superclass of the object");
- }
- }
- this.upToClass = clazz;
- }
-
- /**
- *
- * Gets the String built by this builder.
- *
- *
- * @return the built string
- */
- @Override
- public String toString() {
- if (this.getObject() == null) {
- return this.getStyle().getNullText();
- }
- Class> clazz = this.getObject().getClass();
- this.appendFieldsIn(clazz);
- while (clazz.getSuperclass() != null && clazz != this.getUpToClass()) {
- clazz = clazz.getSuperclass();
- this.appendFieldsIn(clazz);
- }
- return super.toString();
- }
-
-}
diff --git a/core/src/main/java/external/org/apache/commons/lang3/builder/ToStringBuilder.java b/core/src/main/java/external/org/apache/commons/lang3/builder/ToStringBuilder.java
deleted file mode 100644
index 1cb42b5d..00000000
--- a/core/src/main/java/external/org/apache/commons/lang3/builder/ToStringBuilder.java
+++ /dev/null
@@ -1,1079 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package external.org.apache.commons.lang3.builder;
-
-import external.org.apache.commons.lang3.ObjectUtils;
-
-/**
- * Assists in implementing {@link Object#toString()} methods.
- *
- * This class enables a good and consistent toString() to be built for any
- * class or object. This class aims to simplify the process by:
- *
- * allowing field names
- * handling all types consistently
- * handling nulls consistently
- * outputting arrays and multi-dimensional arrays
- * enabling the detail level to be controlled for Objects and Collections
- * handling class hierarchies
- *
- *
- * To use this class write code as follows:
- *
- *
- * public class Person {
- * String name;
- * int age;
- * boolean smoker;
- *
- * ...
- *
- * public String toString() {
- * return new ToStringBuilder(this).
- * append("name", name).
- * append("age", age).
- * append("smoker", smoker).
- * toString();
- * }
- * }
- *
- *
- * This will produce a toString of the format:
- * Person@7f54[name=Stephen,age=29,smoker=false]
- *
- * To add the superclass toString, use {@link #appendSuper}.
- * To append the toString from an object that is delegated
- * to (or any other object), use {@link #appendToString}.
- *
- * Alternatively, there is a method that uses reflection to determine
- * the fields to test. Because these fields are usually private, the method,
- * reflectionToString, uses AccessibleObject.setAccessible to
- * change the visibility of the fields. This will fail under a security manager,
- * unless the appropriate permissions are set up correctly. It is also
- * slower than testing explicitly.
- *
- * A typical invocation for this method would look like:
- *
- *
- * public String toString() {
- * return ToStringBuilder.reflectionToString(this);
- * }
- *
- *
- * You can also use the builder to debug 3rd party objects:
- *
- *
- * System.out.println("An object: " + ToStringBuilder.reflectionToString(anObject));
- *
- *
- * The exact format of the toString is determined by
- * the {@link ToStringStyle} passed into the constructor.
- *
- * @since 1.0
- * @version $Id: ToStringBuilder.java 1088899 2011-04-05 05:31:27Z bayard $
- */
-public class ToStringBuilder implements Builder {
-
- /**
- * The default style of output to use, not null.
- */
- private static volatile ToStringStyle defaultStyle = ToStringStyle.DEFAULT_STYLE;
-
- //----------------------------------------------------------------------------
-
- /**
- * Gets the default ToStringStyle to use.
- *
- * This method gets a singleton default value, typically for the whole JVM.
- * Changing this default should generally only be done during application startup.
- * It is recommended to pass a ToStringStyle to the constructor instead
- * of using this global default.
- *
- * This method can be used from multiple threads.
- * Internally, a volatile variable is used to provide the guarantee
- * that the latest value set using {@link #setDefaultStyle} is the value returned.
- * It is strongly recommended that the default style is only changed during application startup.
- *
- * One reason for changing the default could be to have a verbose style during
- * development and a compact style in production.
- *
- * @return the default ToStringStyle, never null
- */
- public static ToStringStyle getDefaultStyle() {
- return defaultStyle;
- }
-
- /**
- * Sets the default ToStringStyle to use.
- *
- * This method sets a singleton default value, typically for the whole JVM.
- * Changing this default should generally only be done during application startup.
- * It is recommended to pass a ToStringStyle to the constructor instead
- * of changing this global default.
- *
- * This method is not intended for use from multiple threads.
- * Internally, a volatile variable is used to provide the guarantee
- * that the latest value set is the value returned from {@link #getDefaultStyle}.
- *
- * @param style the default ToStringStyle
- * @throws IllegalArgumentException if the style is null
- */
- public static void setDefaultStyle(ToStringStyle style) {
- if (style == null) {
- throw new IllegalArgumentException("The style must not be null");
- }
- defaultStyle = style;
- }
-
- //----------------------------------------------------------------------------
- /**
- * Uses ReflectionToStringBuilder to generate a
- * toString for the specified object.
- *
- * @param object the Object to be output
- * @return the String result
- * @see ReflectionToStringBuilder#toString(Object)
- */
- public static String reflectionToString(Object object) {
- return ReflectionToStringBuilder.toString(object);
- }
-
- /**
- * Uses ReflectionToStringBuilder to generate a
- * toString for the specified object.
- *
- * @param object the Object to be output
- * @param style the style of the toString to create, may be null
- * @return the String result
- * @see ReflectionToStringBuilder#toString(Object,ToStringStyle)
- */
- public static String reflectionToString(Object object, ToStringStyle style) {
- return ReflectionToStringBuilder.toString(object, style);
- }
-
- /**
- * Uses ReflectionToStringBuilder to generate a
- * toString for the specified object.
- *
- * @param object the Object to be output
- * @param style the style of the toString to create, may be null
- * @param outputTransients whether to include transient fields
- * @return the String result
- * @see ReflectionToStringBuilder#toString(Object,ToStringStyle,boolean)
- */
- public static String reflectionToString(Object object, ToStringStyle style, boolean outputTransients) {
- return ReflectionToStringBuilder.toString(object, style, outputTransients, false, null);
- }
-
- /**
- * Uses ReflectionToStringBuilder to generate a
- * toString for the specified object.
- *
- * @param the type of the object
- * @param object the Object to be output
- * @param style the style of the toString to create, may be null
- * @param outputTransients whether to include transient fields
- * @param reflectUpToClass the superclass to reflect up to (inclusive), may be null
- * @return the String result
- * @see ReflectionToStringBuilder#toString(Object,ToStringStyle,boolean,boolean,Class)
- * @since 2.0
- */
- public static String reflectionToString(
- T object,
- ToStringStyle style,
- boolean outputTransients,
- Class super T> reflectUpToClass) {
- return ReflectionToStringBuilder.toString(object, style, outputTransients, false, reflectUpToClass);
- }
-
- //----------------------------------------------------------------------------
-
- /**
- * Current toString buffer, not null.
- */
- private final StringBuffer buffer;
- /**
- * The object being output, may be null.
- */
- private final Object object;
- /**
- * The style of output to use, not null.
- */
- private final ToStringStyle style;
-
- /**
- * Constructs a builder for the specified object using the default output style.
- *
- * This default style is obtained from {@link #getDefaultStyle()}.
- *
- * @param object the Object to build a toString for, not recommended to be null
- */
- public ToStringBuilder(Object object) {
- this(object, null, null);
- }
-
- /**
- * Constructs a builder for the specified object using the a defined output style.
- *
- * If the style is null, the default style is used.
- *
- * @param object the Object to build a toString for, not recommended to be null
- * @param style the style of the toString to create, null uses the default style
- */
- public ToStringBuilder(Object object, ToStringStyle style) {
- this(object, style, null);
- }
-
- /**
- * Constructs a builder for the specified object.
- *
- * If the style is null, the default style is used.
- *
- * If the buffer is null, a new one is created.
- *
- * @param object the Object to build a toString for, not recommended to be null
- * @param style the style of the toString to create, null uses the default style
- * @param buffer the StringBuffer to populate, may be null
- */
- public ToStringBuilder(Object object, ToStringStyle style, StringBuffer buffer) {
- if (style == null) {
- style = getDefaultStyle();
- }
- if (buffer == null) {
- buffer = new StringBuffer(512);
- }
- this.buffer = buffer;
- this.style = style;
- this.object = object;
-
- style.appendStart(buffer, object);
- }
-
- //----------------------------------------------------------------------------
-
- /**
- * Append to the toString a boolean
- * value.
- *
- * @param value the value to add to the toString
- * @return this
- */
- public ToStringBuilder append(boolean value) {
- style.append(buffer, null, value);
- return this;
- }
-
- //----------------------------------------------------------------------------
-
- /**
- * Append to the toString a boolean
- * array.
- *
- * @param array the array to add to the toString
- * @return this
- */
- public ToStringBuilder append(boolean[] array) {
- style.append(buffer, null, array, null);
- return this;
- }
-
- //----------------------------------------------------------------------------
-
- /**
- * Append to the toString a byte
- * value.
- *
- * @param value the value to add to the toString
- * @return this
- */
- public ToStringBuilder append(byte value) {
- style.append(buffer, null, value);
- return this;
- }
-
- //----------------------------------------------------------------------------
-
- /**
- * Append to the toString a byte
- * array.
- *
- * @param array the array to add to the toString
- * @return this
- */
- public ToStringBuilder append(byte[] array) {
- style.append(buffer, null, array, null);
- return this;
- }
-
- //----------------------------------------------------------------------------
-
- /**
- * Append to the toString a char
- * value.
- *
- * @param value the value to add to the toString
- * @return this
- */
- public ToStringBuilder append(char value) {
- style.append(buffer, null, value);
- return this;
- }
-
- //----------------------------------------------------------------------------
-
- /**
- * Append to the toString a char
- * array.
- *
- * @param array the array to add to the toString
- * @return this
- */
- public ToStringBuilder append(char[] array) {
- style.append(buffer, null, array, null);
- return this;
- }
-
- //----------------------------------------------------------------------------
-
- /**
- * Append to the toString a double
- * value.
- *
- * @param value the value to add to the toString
- * @return this
- */
- public ToStringBuilder append(double value) {
- style.append(buffer, null, value);
- return this;
- }
-
- //----------------------------------------------------------------------------
-
- /**
- * Append to the toString a double
- * array.
- *
- * @param array the array to add to the toString
- * @return this
- */
- public ToStringBuilder append(double[] array) {
- style.append(buffer, null, array, null);
- return this;
- }
-
- //----------------------------------------------------------------------------
-
- /**
- * Append to the toString a float
- * value.
- *
- * @param value the value to add to the toString
- * @return this
- */
- public ToStringBuilder append(float value) {
- style.append(buffer, null, value);
- return this;
- }
-
- //----------------------------------------------------------------------------
-
- /**
- * Append to the toString a float
- * array.
- *
- * @param array the array to add to the toString
- * @return this
- */
- public ToStringBuilder append(float[] array) {
- style.append(buffer, null, array, null);
- return this;
- }
-
- //----------------------------------------------------------------------------
-
- /**
- * Append to the toString an int
- * value.
- *
- * @param value the value to add to the toString
- * @return this
- */
- public ToStringBuilder append(int value) {
- style.append(buffer, null, value);
- return this;
- }
-
- //----------------------------------------------------------------------------
-
- /**
- * Append to the toString an int
- * array.
- *
- * @param array the array to add to the toString
- * @return this
- */
- public ToStringBuilder append(int[] array) {
- style.append(buffer, null, array, null);
- return this;
- }
-
- //----------------------------------------------------------------------------
-
- /**
- * Append to the toString a long
- * value.
- *
- * @param value the value to add to the toString
- * @return this
- */
- public ToStringBuilder append(long value) {
- style.append(buffer, null, value);
- return this;
- }
-
- //----------------------------------------------------------------------------
-
- /**
- * Append to the toString a long
- * array.
- *
- * @param array the array to add to the toString
- * @return this
- */
- public ToStringBuilder append(long[] array) {
- style.append(buffer, null, array, null);
- return this;
- }
-
- //----------------------------------------------------------------------------
-
- /**
- * Append to the toString an Object
- * value.
- *
- * @param obj the value to add to the toString
- * @return this
- */
- public ToStringBuilder append(Object obj) {
- style.append(buffer, null, obj, null);
- return this;
- }
-
- //----------------------------------------------------------------------------
-
- /**
- * Append to the toString an Object
- * array.
- *
- * @param array the array to add to the toString
- * @return this
- */
- public ToStringBuilder append(Object[] array) {
- style.append(buffer, null, array, null);
- return this;
- }
-
- //----------------------------------------------------------------------------
-
- /**
- * Append to the toString a short
- * value.
- *
- * @param value the value to add to the toString
- * @return this
- */
- public ToStringBuilder append(short value) {
- style.append(buffer, null, value);
- return this;
- }
-
- //----------------------------------------------------------------------------
-
- /**
- * Append to the toString a short
- * array.
- *
- * @param array the array to add to the toString
- * @return this
- */
- public ToStringBuilder append(short[] array) {
- style.append(buffer, null, array, null);
- return this;
- }
-
- /**
- * Append to the toString a boolean
- * value.
- *
- * @param fieldName the field name
- * @param value the value to add to the toString
- * @return this
- */
- public ToStringBuilder append(String fieldName, boolean value) {
- style.append(buffer, fieldName, value);
- return this;
- }
-
- /**
- * Append to the toString a boolean
- * array.
- *
- * @param fieldName the field name
- * @param array the array to add to the hashCode
- * @return this
- */
- public ToStringBuilder append(String fieldName, boolean[] array) {
- style.append(buffer, fieldName, array, null);
- return this;
- }
-
- /**
- * Append to the toString a boolean
- * array.
- *
- * A boolean parameter controls the level of detail to show.
- * Setting true will output the array in full. Setting
- * false will output a summary, typically the size of
- * the array.
- *
- * @param fieldName the field name
- * @param array the array to add to the toString
- * @param fullDetail true for detail, false
- * for summary info
- * @return this
- */
- public ToStringBuilder append(String fieldName, boolean[] array, boolean fullDetail) {
- style.append(buffer, fieldName, array, Boolean.valueOf(fullDetail));
- return this;
- }
-
- /**
- * Append to the toString an byte
- * value.
- *
- * @param fieldName the field name
- * @param value the value to add to the toString
- * @return this
- */
- public ToStringBuilder append(String fieldName, byte value) {
- style.append(buffer, fieldName, value);
- return this;
- }
-
- /**
- * Append to the toString a byte array.
- *
- * @param fieldName the field name
- * @param array the array to add to the toString
- * @return this
- */
- public ToStringBuilder append(String fieldName, byte[] array) {
- style.append(buffer, fieldName, array, null);
- return this;
- }
-
- /**
- * Append to the toString a byte
- * array.
- *
- * A boolean parameter controls the level of detail to show.
- * Setting true will output the array in full. Setting
- * false will output a summary, typically the size of
- * the array.
- *
- * @param fieldName the field name
- * @param array the array to add to the toString
- * @param fullDetail true for detail, false
- * for summary info
- * @return this
- */
- public ToStringBuilder append(String fieldName, byte[] array, boolean fullDetail) {
- style.append(buffer, fieldName, array, Boolean.valueOf(fullDetail));
- return this;
- }
-
- /**
- *
Append to the toString a char
- * value.
- *
- * @param fieldName the field name
- * @param value the value to add to the toString
- * @return this
- */
- public ToStringBuilder append(String fieldName, char value) {
- style.append(buffer, fieldName, value);
- return this;
- }
-
- /**
- * Append to the toString a char
- * array.
- *
- * @param fieldName the field name
- * @param array the array to add to the toString
- * @return this
- */
- public ToStringBuilder append(String fieldName, char[] array) {
- style.append(buffer, fieldName, array, null);
- return this;
- }
-
- /**
- * Append to the toString a char
- * array.
- *
- * A boolean parameter controls the level of detail to show.
- * Setting true will output the array in full. Setting
- * false will output a summary, typically the size of
- * the array.
- *
- * @param fieldName the field name
- * @param array the array to add to the toString
- * @param fullDetail true for detail, false
- * for summary info
- * @return this
- */
- public ToStringBuilder append(String fieldName, char[] array, boolean fullDetail) {
- style.append(buffer, fieldName, array, Boolean.valueOf(fullDetail));
- return this;
- }
-
- /**
- * Append to the toString a double
- * value.
- *
- * @param fieldName the field name
- * @param value the value to add to the toString
- * @return this
- */
- public ToStringBuilder append(String fieldName, double value) {
- style.append(buffer, fieldName, value);
- return this;
- }
-
- /**
- * Append to the toString a double
- * array.
- *
- * @param fieldName the field name
- * @param array the array to add to the toString
- * @return this
- */
- public ToStringBuilder append(String fieldName, double[] array) {
- style.append(buffer, fieldName, array, null);
- return this;
- }
-
- /**
- * Append to the toString a double
- * array.
- *
- * A boolean parameter controls the level of detail to show.
- * Setting true will output the array in full. Setting
- * false will output a summary, typically the size of
- * the array.
- *
- * @param fieldName the field name
- * @param array the array to add to the toString
- * @param fullDetail true for detail, false
- * for summary info
- * @return this
- */
- public ToStringBuilder append(String fieldName, double[] array, boolean fullDetail) {
- style.append(buffer, fieldName, array, Boolean.valueOf(fullDetail));
- return this;
- }
-
- /**
- * Append to the toString an float
- * value.
- *
- * @param fieldName the field name
- * @param value the value to add to the toString
- * @return this
- */
- public ToStringBuilder append(String fieldName, float value) {
- style.append(buffer, fieldName, value);
- return this;
- }
-
- /**
- * Append to the toString a float
- * array.
- *
- * @param fieldName the field name
- * @param array the array to add to the toString
- * @return this
- */
- public ToStringBuilder append(String fieldName, float[] array) {
- style.append(buffer, fieldName, array, null);
- return this;
- }
-
- /**
- * Append to the toString a float
- * array.
- *
- * A boolean parameter controls the level of detail to show.
- * Setting true will output the array in full. Setting
- * false will output a summary, typically the size of
- * the array.
- *
- * @param fieldName the field name
- * @param array the array to add to the toString
- * @param fullDetail true for detail, false
- * for summary info
- * @return this
- */
- public ToStringBuilder append(String fieldName, float[] array, boolean fullDetail) {
- style.append(buffer, fieldName, array, Boolean.valueOf(fullDetail));
- return this;
- }
-
- /**
- * Append to the toString an int
- * value.
- *
- * @param fieldName the field name
- * @param value the value to add to the toString
- * @return this
- */
- public ToStringBuilder append(String fieldName, int value) {
- style.append(buffer, fieldName, value);
- return this;
- }
-
- /**
- * Append to the toString an int
- * array.
- *
- * @param fieldName the field name
- * @param array the array to add to the toString
- * @return this
- */
- public ToStringBuilder append(String fieldName, int[] array) {
- style.append(buffer, fieldName, array, null);
- return this;
- }
-
- /**
- * Append to the toString an int
- * array.
- *
- * A boolean parameter controls the level of detail to show.
- * Setting true will output the array in full. Setting
- * false will output a summary, typically the size of
- * the array.
- *
- * @param fieldName the field name
- * @param array the array to add to the toString
- * @param fullDetail true for detail, false
- * for summary info
- * @return this
- */
- public ToStringBuilder append(String fieldName, int[] array, boolean fullDetail) {
- style.append(buffer, fieldName, array, Boolean.valueOf(fullDetail));
- return this;
- }
-
- /**
- * Append to the toString a long
- * value.
- *
- * @param fieldName the field name
- * @param value the value to add to the toString
- * @return this
- */
- public ToStringBuilder append(String fieldName, long value) {
- style.append(buffer, fieldName, value);
- return this;
- }
-
- /**
- * Append to the toString a long
- * array.
- *
- * @param fieldName the field name
- * @param array the array to add to the toString
- * @return this
- */
- public ToStringBuilder append(String fieldName, long[] array) {
- style.append(buffer, fieldName, array, null);
- return this;
- }
-
- /**
- * Append to the toString a long
- * array.
- *
- * A boolean parameter controls the level of detail to show.
- * Setting true will output the array in full. Setting
- * false will output a summary, typically the size of
- * the array.
- *
- * @param fieldName the field name
- * @param array the array to add to the toString
- * @param fullDetail true for detail, false
- * for summary info
- * @return this
- */
- public ToStringBuilder append(String fieldName, long[] array, boolean fullDetail) {
- style.append(buffer, fieldName, array, Boolean.valueOf(fullDetail));
- return this;
- }
-
- /**
- * Append to the toString an Object
- * value.
- *
- * @param fieldName the field name
- * @param obj the value to add to the toString
- * @return this
- */
- public ToStringBuilder append(String fieldName, Object obj) {
- style.append(buffer, fieldName, obj, null);
- return this;
- }
-
- /**
- * Append to the toString an Object
- * value.
- *
- * @param fieldName the field name
- * @param obj the value to add to the toString
- * @param fullDetail true for detail,
- * false for summary info
- * @return this
- */
- public ToStringBuilder append(String fieldName, Object obj, boolean fullDetail) {
- style.append(buffer, fieldName, obj, Boolean.valueOf(fullDetail));
- return this;
- }
-
- /**
- * Append to the toString an Object
- * array.
- *
- * @param fieldName the field name
- * @param array the array to add to the toString
- * @return this
- */
- public ToStringBuilder append(String fieldName, Object[] array) {
- style.append(buffer, fieldName, array, null);
- return this;
- }
-
- /**
- * Append to the toString an Object
- * array.
- *
- * A boolean parameter controls the level of detail to show.
- * Setting true will output the array in full. Setting
- * false will output a summary, typically the size of
- * the array.
- *
- * @param fieldName the field name
- * @param array the array to add to the toString
- * @param fullDetail true for detail, false
- * for summary info
- * @return this
- */
- public ToStringBuilder append(String fieldName, Object[] array, boolean fullDetail) {
- style.append(buffer, fieldName, array, Boolean.valueOf(fullDetail));
- return this;
- }
-
- /**
- * Append to the toString an short
- * value.
- *
- * @param fieldName the field name
- * @param value the value to add to the toString
- * @return this
- */
- public ToStringBuilder append(String fieldName, short value) {
- style.append(buffer, fieldName, value);
- return this;
- }
-
- /**
- * Append to the toString a short
- * array.
- *
- * @param fieldName the field name
- * @param array the array to add to the toString
- * @return this
- */
- public ToStringBuilder append(String fieldName, short[] array) {
- style.append(buffer, fieldName, array, null);
- return this;
- }
-
- /**
- * Append to the toString a short
- * array.
- *
- * A boolean parameter controls the level of detail to show.
- * Setting true will output the array in full. Setting
- * false will output a summary, typically the size of
- * the array.
- *
- * @param fieldName the field name
- * @param array the array to add to the toString
- * @param fullDetail true for detail, false
- * for summary info
- * @return this
- */
- public ToStringBuilder append(String fieldName, short[] array, boolean fullDetail) {
- style.append(buffer, fieldName, array, Boolean.valueOf(fullDetail));
- return this;
- }
-
- /**
- *
Appends with the same format as the default Object toString()
- * method. Appends the class name followed by
- * {@link System#identityHashCode(java.lang.Object)}.
- *
- * @param object the Object whose class name and id to output
- * @return this
- * @since 2.0
- */
- public ToStringBuilder appendAsObjectToString(Object object) {
- ObjectUtils.identityToString(this.getStringBuffer(), object);
- return this;
- }
-
- //----------------------------------------------------------------------------
-
- /**
- * Append the toString from the superclass.
- *
- * This method assumes that the superclass uses the same ToStringStyle
- * as this one.
- *
- * If superToString is null, no change is made.
- *
- * @param superToString the result of super.toString()
- * @return this
- * @since 2.0
- */
- public ToStringBuilder appendSuper(String superToString) {
- if (superToString != null) {
- style.appendSuper(buffer, superToString);
- }
- return this;
- }
-
- /**
- * Append the toString from another object.
- *
- * This method is useful where a class delegates most of the implementation of
- * its properties to another class. You can then call toString() on
- * the other class and pass the result into this method.
- *
- *
- * private AnotherObject delegate;
- * private String fieldInThisClass;
- *
- * public String toString() {
- * return new ToStringBuilder(this).
- * appendToString(delegate.toString()).
- * append(fieldInThisClass).
- * toString();
- * }
- *
- * This method assumes that the other object uses the same ToStringStyle
- * as this one.
- *
- * If the toString is null, no change is made.
- *
- * @param toString the result of toString() on another object
- * @return this
- * @since 2.0
- */
- public ToStringBuilder appendToString(String toString) {
- if (toString != null) {
- style.appendToString(buffer, toString);
- }
- return this;
- }
-
- /**
- * Returns the Object being output.
- *
- * @return The object being output.
- * @since 2.0
- */
- public Object getObject() {
- return object;
- }
-
- /**
- * Gets the StringBuffer being populated.
- *
- * @return the StringBuffer being populated
- */
- public StringBuffer getStringBuffer() {
- return buffer;
- }
-
- //----------------------------------------------------------------------------
-
- /**
- * Gets the ToStringStyle being used.
- *
- * @return the ToStringStyle being used
- * @since 2.0
- */
- public ToStringStyle getStyle() {
- return style;
- }
-
- /**
- * Returns the built toString.
- *
- * This method appends the end of data indicator, and can only be called once.
- * Use {@link #getStringBuffer} to get the current string state.
- *
- * If the object is null, return the style's nullText
- *
- * @return the String toString
- */
- @Override
- public String toString() {
- if (this.getObject() == null) {
- this.getStringBuffer().append(this.getStyle().getNullText());
- } else {
- style.appendEnd(this.getStringBuffer(), this.getObject());
- }
- return this.getStringBuffer().toString();
- }
-
- /**
- * Returns the String that was build as an object representation. The
- * default implementation utilizes the {@link #toString()} implementation.
- *
- * @return the String toString
- *
- * @see #toString()
- *
- * @since 3.0
- */
- public String build() {
- return toString();
- }
-}
diff --git a/core/src/main/java/external/org/apache/commons/lang3/builder/ToStringStyle.java b/core/src/main/java/external/org/apache/commons/lang3/builder/ToStringStyle.java
deleted file mode 100644
index 783ae6f6..00000000
--- a/core/src/main/java/external/org/apache/commons/lang3/builder/ToStringStyle.java
+++ /dev/null
@@ -1,2271 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package external.org.apache.commons.lang3.builder;
-
-import java.io.Serializable;
-import java.lang.reflect.Array;
-import java.util.Collection;
-import java.util.Map;
-import java.util.WeakHashMap;
-
-import external.org.apache.commons.lang3.ClassUtils;
-import external.org.apache.commons.lang3.ObjectUtils;
-import external.org.apache.commons.lang3.SystemUtils;
-
-/**
- * Controls String formatting for {@link ToStringBuilder}.
- * The main public interface is always via ToStringBuilder.
- *
- * These classes are intended to be used as Singletons.
- * There is no need to instantiate a new style each time. A program
- * will generally use one of the predefined constants on this class.
- * Alternatively, the {@link StandardToStringStyle} class can be used
- * to set the individual settings. Thus most styles can be achieved
- * without subclassing.
- *
- * If required, a subclass can override as many or as few of the
- * methods as it requires. Each object type (from boolean
- * to long to Object to int[]) has
- * its own methods to output it. Most have two versions, detail and summary.
- *
- *
For example, the detail version of the array based methods will
- * output the whole array, whereas the summary method will just output
- * the array length.
- *
- * If you want to format the output of certain objects, such as dates, you
- * must create a subclass and override a method.
- *
- * public class MyStyle extends ToStringStyle {
- * protected void appendDetail(StringBuffer buffer, String fieldName, Object value) {
- * if (value instanceof Date) {
- * value = new SimpleDateFormat("yyyy-MM-dd").format(value);
- * }
- * buffer.append(value);
- * }
- * }
- *
- *
- *
- * @since 1.0
- * @version $Id: ToStringStyle.java 1091066 2011-04-11 13:30:11Z mbenson $
- */
-public abstract class ToStringStyle implements Serializable {
-
- /**
- * Serialization version ID.
- */
- private static final long serialVersionUID = -2587890625525655916L;
-
- /**
- * The default toString style. Using the Using the Person
- * example from {@link ToStringBuilder}, the output would look like this:
- *
- *
- * Person@182f0db[name=John Doe,age=33,smoker=false]
- *
- */
- public static final ToStringStyle DEFAULT_STYLE = new DefaultToStringStyle();
-
- /**
- * The multi line toString style. Using the Using the Person
- * example from {@link ToStringBuilder}, the output would look like this:
- *
- *
- * Person@182f0db[
- * name=John Doe
- * age=33
- * smoker=false
- * ]
- *
- */
- public static final ToStringStyle MULTI_LINE_STYLE = new MultiLineToStringStyle();
-
- /**
- * The no field names toString style. Using the Using the
- * Person example from {@link ToStringBuilder}, the output
- * would look like this:
- *
- *
- * Person@182f0db[John Doe,33,false]
- *
- */
- public static final ToStringStyle NO_FIELD_NAMES_STYLE = new NoFieldNameToStringStyle();
-
- /**
- * The short prefix toString style. Using the Person example
- * from {@link ToStringBuilder}, the output would look like this:
- *
- *
- * Person[name=John Doe,age=33,smoker=false]
- *
- *
- * @since 2.1
- */
- public static final ToStringStyle SHORT_PREFIX_STYLE = new ShortPrefixToStringStyle();
-
- /**
- * The simple toString style. Using the Using the Person
- * example from {@link ToStringBuilder}, the output would look like this:
- *
- *
- * John Doe,33,false
- *
- */
- public static final ToStringStyle SIMPLE_STYLE = new SimpleToStringStyle();
-
- /**
- *
- * A registry of objects used by reflectionToString methods
- * to detect cyclical object references and avoid infinite loops.
- *
- */
- private static final ThreadLocal> REGISTRY =
- new ThreadLocal>();
-
- /**
- *
- * Returns the registry of objects being traversed by the reflectionToString
- * methods in the current thread.
- *
- *
- * @return Set the registry of objects being traversed
- */
- static Map getRegistry() {
- return REGISTRY.get();
- }
-
- /**
- *
- * Returns true if the registry contains the given object.
- * Used by the reflection methods to avoid infinite loops.
- *
- *
- * @param value
- * The object to lookup in the registry.
- * @return boolean true if the registry contains the given
- * object.
- */
- static boolean isRegistered(Object value) {
- Map m = getRegistry();
- return m != null && m.containsKey(value);
- }
-
- /**
- *
- * Registers the given object. Used by the reflection methods to avoid
- * infinite loops.
- *
- *
- * @param value
- * The object to register.
- */
- static void register(Object value) {
- if (value != null) {
- Map m = getRegistry();
- if (m == null) {
- REGISTRY.set(new WeakHashMap());
- }
- getRegistry().put(value, null);
- }
- }
-
- /**
- *
- * Unregisters the given object.
- *
- *
- *
- * Used by the reflection methods to avoid infinite loops.
- *
- *
- * @param value
- * The object to unregister.
- */
- static void unregister(Object value) {
- if (value != null) {
- Map m = getRegistry();
- if (m != null) {
- m.remove(value);
- if (m.isEmpty()) {
- REGISTRY.remove();
- }
- }
- }
- }
-
- /**
- * Whether to use the field names, the default is true.
- */
- private boolean useFieldNames = true;
-
- /**
- * Whether to use the class name, the default is true.
- */
- private boolean useClassName = true;
-
- /**
- * Whether to use short class names, the default is false.
- */
- private boolean useShortClassName = false;
-
- /**
- * Whether to use the identity hash code, the default is true.
- */
- private boolean useIdentityHashCode = true;
-
- /**
- * The content start '['.
- */
- private String contentStart = "[";
-
- /**
- * The content end ']'.
- */
- private String contentEnd = "]";
-
- /**
- * The field name value separator '='.
- */
- private String fieldNameValueSeparator = "=";
-
- /**
- * Whether the field separator should be added before any other fields.
- */
- private boolean fieldSeparatorAtStart = false;
-
- /**
- * Whether the field separator should be added after any other fields.
- */
- private boolean fieldSeparatorAtEnd = false;
-
- /**
- * The field separator ','.
- */
- private String fieldSeparator = ",";
-
- /**
- * The array start '{'.
- */
- private String arrayStart = "{";
-
- /**
- * The array separator ','.
- */
- private String arraySeparator = ",";
-
- /**
- * The detail for array content.
- */
- private boolean arrayContentDetail = true;
-
- /**
- * The array end '}'.
- */
- private String arrayEnd = "}";
-
- /**
- * The value to use when fullDetail is null,
- * the default value is true.
- */
- private boolean defaultFullDetail = true;
-
- /**
- * The null text '<null>'.
- */
- private String nullText = "";
-
- /**
- * The summary size text start '.
- */
- private String sizeStartText = "'>' .
- */
- private String sizeEndText = ">";
-
- /**
- * The summary object text start '<'.
- */
- private String summaryObjectStartText = "<";
-
- /**
- * The summary object text start '>'.
- */
- private String summaryObjectEndText = ">";
-
- //----------------------------------------------------------------------------
-
- /**
- * Constructor.
- */
- protected ToStringStyle() {
- super();
- }
-
- //----------------------------------------------------------------------------
-
- /**
- * Append to the toString the superclass toString.
- * NOTE: It assumes that the toString has been created from the same ToStringStyle.
- *
- * A null superToString is ignored.
- *
- * @param buffer the StringBuffer to populate
- * @param superToString the super.toString()
- * @since 2.0
- */
- public void appendSuper(StringBuffer buffer, String superToString) {
- appendToString(buffer, superToString);
- }
-
- /**
- * Append to the toString another toString.
- * NOTE: It assumes that the toString has been created from the same ToStringStyle.
- *
- * A null toString is ignored.
- *
- * @param buffer the StringBuffer to populate
- * @param toString the additional toString
- * @since 2.0
- */
- public void appendToString(StringBuffer buffer, String toString) {
- if (toString != null) {
- int pos1 = toString.indexOf(contentStart) + contentStart.length();
- int pos2 = toString.lastIndexOf(contentEnd);
- if (pos1 != pos2 && pos1 >= 0 && pos2 >= 0) {
- String data = toString.substring(pos1, pos2);
- if (fieldSeparatorAtStart) {
- removeLastFieldSeparator(buffer);
- }
- buffer.append(data);
- appendFieldSeparator(buffer);
- }
- }
- }
-
- /**
- * Append to the toString the start of data indicator.
- *
- * @param buffer the StringBuffer to populate
- * @param object the Object to build a toString for
- */
- public void appendStart(StringBuffer buffer, Object object) {
- if (object != null) {
- appendClassName(buffer, object);
- appendIdentityHashCode(buffer, object);
- appendContentStart(buffer);
- if (fieldSeparatorAtStart) {
- appendFieldSeparator(buffer);
- }
- }
- }
-
- /**
- * Append to the toString the end of data indicator.
- *
- * @param buffer the StringBuffer to populate
- * @param object the Object to build a
- * toString for.
- */
- public void appendEnd(StringBuffer buffer, Object object) {
- if (this.fieldSeparatorAtEnd == false) {
- removeLastFieldSeparator(buffer);
- }
- appendContentEnd(buffer);
- unregister(object);
- }
-
- /**
- * Remove the last field separator from the buffer.
- *
- * @param buffer the StringBuffer to populate
- * @since 2.0
- */
- protected void removeLastFieldSeparator(StringBuffer buffer) {
- int len = buffer.length();
- int sepLen = fieldSeparator.length();
- if (len > 0 && sepLen > 0 && len >= sepLen) {
- boolean match = true;
- for (int i = 0; i < sepLen; i++) {
- if (buffer.charAt(len - 1 - i) != fieldSeparator.charAt(sepLen - 1 - i)) {
- match = false;
- break;
- }
- }
- if (match) {
- buffer.setLength(len - sepLen);
- }
- }
- }
-
- //----------------------------------------------------------------------------
-
- /**
- * Append to the toString an Object
- * value, printing the full toString of the
- * Object passed in.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name
- * @param value the value to add to the toString
- * @param fullDetail true for detail, false
- * for summary info, null for style decides
- */
- public void append(StringBuffer buffer, String fieldName, Object value, Boolean fullDetail) {
- appendFieldStart(buffer, fieldName);
-
- if (value == null) {
- appendNullText(buffer, fieldName);
-
- } else {
- appendInternal(buffer, fieldName, value, isFullDetail(fullDetail));
- }
-
- appendFieldEnd(buffer, fieldName);
- }
-
- /**
- * Append to the toString an Object,
- * correctly interpreting its type.
- *
- * This method performs the main lookup by Class type to correctly
- * route arrays, Collections, Maps and
- * Objects to the appropriate method.
- *
- * Either detail or summary views can be specified.
- *
- * If a cycle is detected, an object will be appended with the
- * Object.toString() format.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name, typically not used as already appended
- * @param value the value to add to the toString,
- * not null
- * @param detail output detail or not
- */
- protected void appendInternal(StringBuffer buffer, String fieldName, Object value, boolean detail) {
- if (isRegistered(value)
- && !(value instanceof Number || value instanceof Boolean || value instanceof Character)) {
- appendCyclicObject(buffer, fieldName, value);
- return;
- }
-
- register(value);
-
- try {
- if (value instanceof Collection>) {
- if (detail) {
- appendDetail(buffer, fieldName, (Collection>) value);
- } else {
- appendSummarySize(buffer, fieldName, ((Collection>) value).size());
- }
-
- } else if (value instanceof Map, ?>) {
- if (detail) {
- appendDetail(buffer, fieldName, (Map, ?>) value);
- } else {
- appendSummarySize(buffer, fieldName, ((Map, ?>) value).size());
- }
-
- } else if (value instanceof long[]) {
- if (detail) {
- appendDetail(buffer, fieldName, (long[]) value);
- } else {
- appendSummary(buffer, fieldName, (long[]) value);
- }
-
- } else if (value instanceof int[]) {
- if (detail) {
- appendDetail(buffer, fieldName, (int[]) value);
- } else {
- appendSummary(buffer, fieldName, (int[]) value);
- }
-
- } else if (value instanceof short[]) {
- if (detail) {
- appendDetail(buffer, fieldName, (short[]) value);
- } else {
- appendSummary(buffer, fieldName, (short[]) value);
- }
-
- } else if (value instanceof byte[]) {
- if (detail) {
- appendDetail(buffer, fieldName, (byte[]) value);
- } else {
- appendSummary(buffer, fieldName, (byte[]) value);
- }
-
- } else if (value instanceof char[]) {
- if (detail) {
- appendDetail(buffer, fieldName, (char[]) value);
- } else {
- appendSummary(buffer, fieldName, (char[]) value);
- }
-
- } else if (value instanceof double[]) {
- if (detail) {
- appendDetail(buffer, fieldName, (double[]) value);
- } else {
- appendSummary(buffer, fieldName, (double[]) value);
- }
-
- } else if (value instanceof float[]) {
- if (detail) {
- appendDetail(buffer, fieldName, (float[]) value);
- } else {
- appendSummary(buffer, fieldName, (float[]) value);
- }
-
- } else if (value instanceof boolean[]) {
- if (detail) {
- appendDetail(buffer, fieldName, (boolean[]) value);
- } else {
- appendSummary(buffer, fieldName, (boolean[]) value);
- }
-
- } else if (value.getClass().isArray()) {
- if (detail) {
- appendDetail(buffer, fieldName, (Object[]) value);
- } else {
- appendSummary(buffer, fieldName, (Object[]) value);
- }
-
- } else {
- if (detail) {
- appendDetail(buffer, fieldName, value);
- } else {
- appendSummary(buffer, fieldName, value);
- }
- }
- } finally {
- unregister(value);
- }
- }
-
- /**
- * Append to the toString an Object
- * value that has been detected to participate in a cycle. This
- * implementation will print the standard string value of the value.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name, typically not used as already appended
- * @param value the value to add to the toString,
- * not null
- *
- * @since 2.2
- */
- protected void appendCyclicObject(StringBuffer buffer, String fieldName, Object value) {
- ObjectUtils.identityToString(buffer, value);
- }
-
- /**
- * Append to the toString an Object
- * value, printing the full detail of the Object.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name, typically not used as already appended
- * @param value the value to add to the toString,
- * not null
- */
- protected void appendDetail(StringBuffer buffer, String fieldName, Object value) {
- buffer.append(value);
- }
-
- /**
- * Append to the toString a Collection.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name, typically not used as already appended
- * @param coll the Collection to add to the
- * toString, not null
- */
- protected void appendDetail(StringBuffer buffer, String fieldName, Collection> coll) {
- buffer.append(coll);
- }
-
- /**
- * Append to the toString a Map.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name, typically not used as already appended
- * @param map the Map to add to the toString,
- * not null
- */
- protected void appendDetail(StringBuffer buffer, String fieldName, Map, ?> map) {
- buffer.append(map);
- }
-
- /**
- * Append to the toString an Object
- * value, printing a summary of the Object.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name, typically not used as already appended
- * @param value the value to add to the toString,
- * not null
- */
- protected void appendSummary(StringBuffer buffer, String fieldName, Object value) {
- buffer.append(summaryObjectStartText);
- buffer.append(getShortClassName(value.getClass()));
- buffer.append(summaryObjectEndText);
- }
-
- //----------------------------------------------------------------------------
-
- /**
- * Append to the toString a long
- * value.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name
- * @param value the value to add to the toString
- */
- public void append(StringBuffer buffer, String fieldName, long value) {
- appendFieldStart(buffer, fieldName);
- appendDetail(buffer, fieldName, value);
- appendFieldEnd(buffer, fieldName);
- }
-
- /**
- * Append to the toString a long
- * value.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name, typically not used as already appended
- * @param value the value to add to the toString
- */
- protected void appendDetail(StringBuffer buffer, String fieldName, long value) {
- buffer.append(value);
- }
-
- //----------------------------------------------------------------------------
-
- /**
- * Append to the toString an int
- * value.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name
- * @param value the value to add to the toString
- */
- public void append(StringBuffer buffer, String fieldName, int value) {
- appendFieldStart(buffer, fieldName);
- appendDetail(buffer, fieldName, value);
- appendFieldEnd(buffer, fieldName);
- }
-
- /**
- * Append to the toString an int
- * value.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name, typically not used as already appended
- * @param value the value to add to the toString
- */
- protected void appendDetail(StringBuffer buffer, String fieldName, int value) {
- buffer.append(value);
- }
-
- //----------------------------------------------------------------------------
-
- /**
- * Append to the toString a short
- * value.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name
- * @param value the value to add to the toString
- */
- public void append(StringBuffer buffer, String fieldName, short value) {
- appendFieldStart(buffer, fieldName);
- appendDetail(buffer, fieldName, value);
- appendFieldEnd(buffer, fieldName);
- }
-
- /**
- * Append to the toString a short
- * value.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name, typically not used as already appended
- * @param value the value to add to the toString
- */
- protected void appendDetail(StringBuffer buffer, String fieldName, short value) {
- buffer.append(value);
- }
-
- //----------------------------------------------------------------------------
-
- /**
- * Append to the toString a byte
- * value.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name
- * @param value the value to add to the toString
- */
- public void append(StringBuffer buffer, String fieldName, byte value) {
- appendFieldStart(buffer, fieldName);
- appendDetail(buffer, fieldName, value);
- appendFieldEnd(buffer, fieldName);
- }
-
- /**
- * Append to the toString a byte
- * value.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name, typically not used as already appended
- * @param value the value to add to the toString
- */
- protected void appendDetail(StringBuffer buffer, String fieldName, byte value) {
- buffer.append(value);
- }
-
- //----------------------------------------------------------------------------
-
- /**
- * Append to the toString a char
- * value.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name
- * @param value the value to add to the toString
- */
- public void append(StringBuffer buffer, String fieldName, char value) {
- appendFieldStart(buffer, fieldName);
- appendDetail(buffer, fieldName, value);
- appendFieldEnd(buffer, fieldName);
- }
-
- /**
- * Append to the toString a char
- * value.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name, typically not used as already appended
- * @param value the value to add to the toString
- */
- protected void appendDetail(StringBuffer buffer, String fieldName, char value) {
- buffer.append(value);
- }
-
- //----------------------------------------------------------------------------
-
- /**
- * Append to the toString a double
- * value.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name
- * @param value the value to add to the toString
- */
- public void append(StringBuffer buffer, String fieldName, double value) {
- appendFieldStart(buffer, fieldName);
- appendDetail(buffer, fieldName, value);
- appendFieldEnd(buffer, fieldName);
- }
-
- /**
- * Append to the toString a double
- * value.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name, typically not used as already appended
- * @param value the value to add to the toString
- */
- protected void appendDetail(StringBuffer buffer, String fieldName, double value) {
- buffer.append(value);
- }
-
- //----------------------------------------------------------------------------
-
- /**
- * Append to the toString a float
- * value.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name
- * @param value the value to add to the toString
- */
- public void append(StringBuffer buffer, String fieldName, float value) {
- appendFieldStart(buffer, fieldName);
- appendDetail(buffer, fieldName, value);
- appendFieldEnd(buffer, fieldName);
- }
-
- /**
- * Append to the toString a float
- * value.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name, typically not used as already appended
- * @param value the value to add to the toString
- */
- protected void appendDetail(StringBuffer buffer, String fieldName, float value) {
- buffer.append(value);
- }
-
- //----------------------------------------------------------------------------
-
- /**
- * Append to the toString a boolean
- * value.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name
- * @param value the value to add to the toString
- */
- public void append(StringBuffer buffer, String fieldName, boolean value) {
- appendFieldStart(buffer, fieldName);
- appendDetail(buffer, fieldName, value);
- appendFieldEnd(buffer, fieldName);
- }
-
- /**
- * Append to the toString a boolean
- * value.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name, typically not used as already appended
- * @param value the value to add to the toString
- */
- protected void appendDetail(StringBuffer buffer, String fieldName, boolean value) {
- buffer.append(value);
- }
-
- /**
- * Append to the toString an Object
- * array.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name
- * @param array the array to add to the toString
- * @param fullDetail true for detail, false
- * for summary info, null for style decides
- */
- public void append(StringBuffer buffer, String fieldName, Object[] array, Boolean fullDetail) {
- appendFieldStart(buffer, fieldName);
-
- if (array == null) {
- appendNullText(buffer, fieldName);
-
- } else if (isFullDetail(fullDetail)) {
- appendDetail(buffer, fieldName, array);
-
- } else {
- appendSummary(buffer, fieldName, array);
- }
-
- appendFieldEnd(buffer, fieldName);
- }
-
- //----------------------------------------------------------------------------
-
- /**
- * Append to the toString the detail of an
- * Object array.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name, typically not used as already appended
- * @param array the array to add to the toString,
- * not null
- */
- protected void appendDetail(StringBuffer buffer, String fieldName, Object[] array) {
- buffer.append(arrayStart);
- for (int i = 0; i < array.length; i++) {
- Object item = array[i];
- if (i > 0) {
- buffer.append(arraySeparator);
- }
- if (item == null) {
- appendNullText(buffer, fieldName);
-
- } else {
- appendInternal(buffer, fieldName, item, arrayContentDetail);
- }
- }
- buffer.append(arrayEnd);
- }
-
- /**
- * Append to the toString the detail of an array type.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name, typically not used as already appended
- * @param array the array to add to the toString,
- * not null
- * @since 2.0
- */
- protected void reflectionAppendArrayDetail(StringBuffer buffer, String fieldName, Object array) {
- buffer.append(arrayStart);
- int length = Array.getLength(array);
- for (int i = 0; i < length; i++) {
- Object item = Array.get(array, i);
- if (i > 0) {
- buffer.append(arraySeparator);
- }
- if (item == null) {
- appendNullText(buffer, fieldName);
-
- } else {
- appendInternal(buffer, fieldName, item, arrayContentDetail);
- }
- }
- buffer.append(arrayEnd);
- }
-
- /**
- * Append to the toString a summary of an
- * Object array.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name, typically not used as already appended
- * @param array the array to add to the toString,
- * not null
- */
- protected void appendSummary(StringBuffer buffer, String fieldName, Object[] array) {
- appendSummarySize(buffer, fieldName, array.length);
- }
-
- //----------------------------------------------------------------------------
-
- /**
- * Append to the toString a long
- * array.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name
- * @param array the array to add to the toString
- * @param fullDetail true for detail, false
- * for summary info, null for style decides
- */
- public void append(StringBuffer buffer, String fieldName, long[] array, Boolean fullDetail) {
- appendFieldStart(buffer, fieldName);
-
- if (array == null) {
- appendNullText(buffer, fieldName);
-
- } else if (isFullDetail(fullDetail)) {
- appendDetail(buffer, fieldName, array);
-
- } else {
- appendSummary(buffer, fieldName, array);
- }
-
- appendFieldEnd(buffer, fieldName);
- }
-
- /**
- * Append to the toString the detail of a
- * long array.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name, typically not used as already appended
- * @param array the array to add to the toString,
- * not null
- */
- protected void appendDetail(StringBuffer buffer, String fieldName, long[] array) {
- buffer.append(arrayStart);
- for (int i = 0; i < array.length; i++) {
- if (i > 0) {
- buffer.append(arraySeparator);
- }
- appendDetail(buffer, fieldName, array[i]);
- }
- buffer.append(arrayEnd);
- }
-
- /**
- * Append to the toString a summary of a
- * long array.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name, typically not used as already appended
- * @param array the array to add to the toString,
- * not null
- */
- protected void appendSummary(StringBuffer buffer, String fieldName, long[] array) {
- appendSummarySize(buffer, fieldName, array.length);
- }
-
- //----------------------------------------------------------------------------
-
- /**
- * Append to the toString an int
- * array.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name
- * @param array the array to add to the toString
- * @param fullDetail true for detail, false
- * for summary info, null for style decides
- */
- public void append(StringBuffer buffer, String fieldName, int[] array, Boolean fullDetail) {
- appendFieldStart(buffer, fieldName);
-
- if (array == null) {
- appendNullText(buffer, fieldName);
-
- } else if (isFullDetail(fullDetail)) {
- appendDetail(buffer, fieldName, array);
-
- } else {
- appendSummary(buffer, fieldName, array);
- }
-
- appendFieldEnd(buffer, fieldName);
- }
-
- /**
- * Append to the toString the detail of an
- * int array.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name, typically not used as already appended
- * @param array the array to add to the toString,
- * not null
- */
- protected void appendDetail(StringBuffer buffer, String fieldName, int[] array) {
- buffer.append(arrayStart);
- for (int i = 0; i < array.length; i++) {
- if (i > 0) {
- buffer.append(arraySeparator);
- }
- appendDetail(buffer, fieldName, array[i]);
- }
- buffer.append(arrayEnd);
- }
-
- /**
- * Append to the toString a summary of an
- * int array.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name, typically not used as already appended
- * @param array the array to add to the toString,
- * not null
- */
- protected void appendSummary(StringBuffer buffer, String fieldName, int[] array) {
- appendSummarySize(buffer, fieldName, array.length);
- }
-
- //----------------------------------------------------------------------------
-
- /**
- * Append to the toString a short
- * array.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name
- * @param array the array to add to the toString
- * @param fullDetail true for detail, false
- * for summary info, null for style decides
- */
- public void append(StringBuffer buffer, String fieldName, short[] array, Boolean fullDetail) {
- appendFieldStart(buffer, fieldName);
-
- if (array == null) {
- appendNullText(buffer, fieldName);
-
- } else if (isFullDetail(fullDetail)) {
- appendDetail(buffer, fieldName, array);
-
- } else {
- appendSummary(buffer, fieldName, array);
- }
-
- appendFieldEnd(buffer, fieldName);
- }
-
- /**
- * Append to the toString the detail of a
- * short array.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name, typically not used as already appended
- * @param array the array to add to the toString,
- * not null
- */
- protected void appendDetail(StringBuffer buffer, String fieldName, short[] array) {
- buffer.append(arrayStart);
- for (int i = 0; i < array.length; i++) {
- if (i > 0) {
- buffer.append(arraySeparator);
- }
- appendDetail(buffer, fieldName, array[i]);
- }
- buffer.append(arrayEnd);
- }
-
- /**
- * Append to the toString a summary of a
- * short array.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name, typically not used as already appended
- * @param array the array to add to the toString,
- * not null
- */
- protected void appendSummary(StringBuffer buffer, String fieldName, short[] array) {
- appendSummarySize(buffer, fieldName, array.length);
- }
-
- //----------------------------------------------------------------------------
-
- /**
- * Append to the toString a byte
- * array.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name
- * @param array the array to add to the toString
- * @param fullDetail true for detail, false
- * for summary info, null for style decides
- */
- public void append(StringBuffer buffer, String fieldName, byte[] array, Boolean fullDetail) {
- appendFieldStart(buffer, fieldName);
-
- if (array == null) {
- appendNullText(buffer, fieldName);
-
- } else if (isFullDetail(fullDetail)) {
- appendDetail(buffer, fieldName, array);
-
- } else {
- appendSummary(buffer, fieldName, array);
- }
-
- appendFieldEnd(buffer, fieldName);
- }
-
- /**
- * Append to the toString the detail of a
- * byte array.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name, typically not used as already appended
- * @param array the array to add to the toString,
- * not null
- */
- protected void appendDetail(StringBuffer buffer, String fieldName, byte[] array) {
- buffer.append(arrayStart);
- for (int i = 0; i < array.length; i++) {
- if (i > 0) {
- buffer.append(arraySeparator);
- }
- appendDetail(buffer, fieldName, array[i]);
- }
- buffer.append(arrayEnd);
- }
-
- /**
- * Append to the toString a summary of a
- * byte array.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name, typically not used as already appended
- * @param array the array to add to the toString,
- * not null
- */
- protected void appendSummary(StringBuffer buffer, String fieldName, byte[] array) {
- appendSummarySize(buffer, fieldName, array.length);
- }
-
- //----------------------------------------------------------------------------
-
- /**
- * Append to the toString a char
- * array.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name
- * @param array the array to add to the toString
- * @param fullDetail true for detail, false
- * for summary info, null for style decides
- */
- public void append(StringBuffer buffer, String fieldName, char[] array, Boolean fullDetail) {
- appendFieldStart(buffer, fieldName);
-
- if (array == null) {
- appendNullText(buffer, fieldName);
-
- } else if (isFullDetail(fullDetail)) {
- appendDetail(buffer, fieldName, array);
-
- } else {
- appendSummary(buffer, fieldName, array);
- }
-
- appendFieldEnd(buffer, fieldName);
- }
-
- /**
- * Append to the toString the detail of a
- * char array.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name, typically not used as already appended
- * @param array the array to add to the toString,
- * not null
- */
- protected void appendDetail(StringBuffer buffer, String fieldName, char[] array) {
- buffer.append(arrayStart);
- for (int i = 0; i < array.length; i++) {
- if (i > 0) {
- buffer.append(arraySeparator);
- }
- appendDetail(buffer, fieldName, array[i]);
- }
- buffer.append(arrayEnd);
- }
-
- /**
- * Append to the toString a summary of a
- * char array.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name, typically not used as already appended
- * @param array the array to add to the toString,
- * not null
- */
- protected void appendSummary(StringBuffer buffer, String fieldName, char[] array) {
- appendSummarySize(buffer, fieldName, array.length);
- }
-
- //----------------------------------------------------------------------------
-
- /**
- * Append to the toString a double
- * array.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name
- * @param array the array to add to the toString
- * @param fullDetail true for detail, false
- * for summary info, null for style decides
- */
- public void append(StringBuffer buffer, String fieldName, double[] array, Boolean fullDetail) {
- appendFieldStart(buffer, fieldName);
-
- if (array == null) {
- appendNullText(buffer, fieldName);
-
- } else if (isFullDetail(fullDetail)) {
- appendDetail(buffer, fieldName, array);
-
- } else {
- appendSummary(buffer, fieldName, array);
- }
-
- appendFieldEnd(buffer, fieldName);
- }
-
- /**
- * Append to the toString the detail of a
- * double array.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name, typically not used as already appended
- * @param array the array to add to the toString,
- * not null
- */
- protected void appendDetail(StringBuffer buffer, String fieldName, double[] array) {
- buffer.append(arrayStart);
- for (int i = 0; i < array.length; i++) {
- if (i > 0) {
- buffer.append(arraySeparator);
- }
- appendDetail(buffer, fieldName, array[i]);
- }
- buffer.append(arrayEnd);
- }
-
- /**
- * Append to the toString a summary of a
- * double array.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name, typically not used as already appended
- * @param array the array to add to the toString,
- * not null
- */
- protected void appendSummary(StringBuffer buffer, String fieldName, double[] array) {
- appendSummarySize(buffer, fieldName, array.length);
- }
-
- //----------------------------------------------------------------------------
-
- /**
- * Append to the toString a float
- * array.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name
- * @param array the array to add to the toString
- * @param fullDetail true for detail, false
- * for summary info, null for style decides
- */
- public void append(StringBuffer buffer, String fieldName, float[] array, Boolean fullDetail) {
- appendFieldStart(buffer, fieldName);
-
- if (array == null) {
- appendNullText(buffer, fieldName);
-
- } else if (isFullDetail(fullDetail)) {
- appendDetail(buffer, fieldName, array);
-
- } else {
- appendSummary(buffer, fieldName, array);
- }
-
- appendFieldEnd(buffer, fieldName);
- }
-
- /**
- * Append to the toString the detail of a
- * float array.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name, typically not used as already appended
- * @param array the array to add to the toString,
- * not null
- */
- protected void appendDetail(StringBuffer buffer, String fieldName, float[] array) {
- buffer.append(arrayStart);
- for (int i = 0; i < array.length; i++) {
- if (i > 0) {
- buffer.append(arraySeparator);
- }
- appendDetail(buffer, fieldName, array[i]);
- }
- buffer.append(arrayEnd);
- }
-
- /**
- * Append to the toString a summary of a
- * float array.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name, typically not used as already appended
- * @param array the array to add to the toString,
- * not null
- */
- protected void appendSummary(StringBuffer buffer, String fieldName, float[] array) {
- appendSummarySize(buffer, fieldName, array.length);
- }
-
- //----------------------------------------------------------------------------
-
- /**
- * Append to the toString a boolean
- * array.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name
- * @param array the array to add to the toString
- * @param fullDetail true for detail, false
- * for summary info, null for style decides
- */
- public void append(StringBuffer buffer, String fieldName, boolean[] array, Boolean fullDetail) {
- appendFieldStart(buffer, fieldName);
-
- if (array == null) {
- appendNullText(buffer, fieldName);
-
- } else if (isFullDetail(fullDetail)) {
- appendDetail(buffer, fieldName, array);
-
- } else {
- appendSummary(buffer, fieldName, array);
- }
-
- appendFieldEnd(buffer, fieldName);
- }
-
- /**
- * Append to the toString the detail of a
- * boolean array.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name, typically not used as already appended
- * @param array the array to add to the toString,
- * not null
- */
- protected void appendDetail(StringBuffer buffer, String fieldName, boolean[] array) {
- buffer.append(arrayStart);
- for (int i = 0; i < array.length; i++) {
- if (i > 0) {
- buffer.append(arraySeparator);
- }
- appendDetail(buffer, fieldName, array[i]);
- }
- buffer.append(arrayEnd);
- }
-
- /**
- * Append to the toString a summary of a
- * boolean array.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name, typically not used as already appended
- * @param array the array to add to the toString,
- * not null
- */
- protected void appendSummary(StringBuffer buffer, String fieldName, boolean[] array) {
- appendSummarySize(buffer, fieldName, array.length);
- }
-
- //----------------------------------------------------------------------------
-
- /**
- * Append to the toString the class name.
- *
- * @param buffer the StringBuffer to populate
- * @param object the Object whose name to output
- */
- protected void appendClassName(StringBuffer buffer, Object object) {
- if (useClassName && object != null) {
- register(object);
- if (useShortClassName) {
- buffer.append(getShortClassName(object.getClass()));
- } else {
- buffer.append(object.getClass().getName());
- }
- }
- }
-
- /**
- * Append the {@link System#identityHashCode(java.lang.Object)}.
- *
- * @param buffer the StringBuffer to populate
- * @param object the Object whose id to output
- */
- protected void appendIdentityHashCode(StringBuffer buffer, Object object) {
- if (this.isUseIdentityHashCode() && object!=null) {
- register(object);
- buffer.append('@');
- buffer.append(Integer.toHexString(System.identityHashCode(object)));
- }
- }
-
- /**
- * Append to the toString the content start.
- *
- * @param buffer the StringBuffer to populate
- */
- protected void appendContentStart(StringBuffer buffer) {
- buffer.append(contentStart);
- }
-
- /**
- * Append to the toString the content end.
- *
- * @param buffer the StringBuffer to populate
- */
- protected void appendContentEnd(StringBuffer buffer) {
- buffer.append(contentEnd);
- }
-
- /**
- * Append to the toString an indicator for null.
- *
- * The default indicator is '<null>'.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name, typically not used as already appended
- */
- protected void appendNullText(StringBuffer buffer, String fieldName) {
- buffer.append(nullText);
- }
-
- /**
- * Append to the toString the field separator.
- *
- * @param buffer the StringBuffer to populate
- */
- protected void appendFieldSeparator(StringBuffer buffer) {
- buffer.append(fieldSeparator);
- }
-
- /**
- * Append to the toString the field start.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name
- */
- protected void appendFieldStart(StringBuffer buffer, String fieldName) {
- if (useFieldNames && fieldName != null) {
- buffer.append(fieldName);
- buffer.append(fieldNameValueSeparator);
- }
- }
-
- /**
- * Append to the toString the field end.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name, typically not used as already appended
- */
- protected void appendFieldEnd(StringBuffer buffer, String fieldName) {
- appendFieldSeparator(buffer);
- }
-
- /**
- * Append to the toString a size summary.
- *
- * The size summary is used to summarize the contents of
- * Collections, Maps and arrays.
- *
- * The output consists of a prefix, the passed in size
- * and a suffix.
- *
- * The default format is '<size=n>'.
- *
- * @param buffer the StringBuffer to populate
- * @param fieldName the field name, typically not used as already appended
- * @param size the size to append
- */
- protected void appendSummarySize(StringBuffer buffer, String fieldName, int size) {
- buffer.append(sizeStartText);
- buffer.append(size);
- buffer.append(sizeEndText);
- }
-
- /**
- * Is this field to be output in full detail.
- *
- * This method converts a detail request into a detail level.
- * The calling code may request full detail (true),
- * but a subclass might ignore that and always return
- * false. The calling code may pass in
- * null indicating that it doesn't care about
- * the detail level. In this case the default detail level is
- * used.
- *
- * @param fullDetailRequest the detail level requested
- * @return whether full detail is to be shown
- */
- protected boolean isFullDetail(Boolean fullDetailRequest) {
- if (fullDetailRequest == null) {
- return defaultFullDetail;
- }
- return fullDetailRequest.booleanValue();
- }
-
- /**
- * Gets the short class name for a class.
- *
- * The short class name is the classname excluding
- * the package name.
- *
- * @param cls the Class to get the short name of
- * @return the short name
- */
- protected String getShortClassName(Class> cls) {
- return ClassUtils.getShortClassName(cls);
- }
-
- // Setters and getters for the customizable parts of the style
- // These methods are not expected to be overridden, except to make public
- // (They are not public so that immutable subclasses can be written)
- //---------------------------------------------------------------------
-
- /**
- * Gets whether to use the class name.
- *
- * @return the current useClassName flag
- */
- protected boolean isUseClassName() {
- return useClassName;
- }
-
- /**
- * Sets whether to use the class name.
- *
- * @param useClassName the new useClassName flag
- */
- protected void setUseClassName(boolean useClassName) {
- this.useClassName = useClassName;
- }
-
- //---------------------------------------------------------------------
-
- /**
- * Gets whether to output short or long class names.
- *
- * @return the current useShortClassName flag
- * @since 2.0
- */
- protected boolean isUseShortClassName() {
- return useShortClassName;
- }
-
- /**
- * Sets whether to output short or long class names.
- *
- * @param useShortClassName the new useShortClassName flag
- * @since 2.0
- */
- protected void setUseShortClassName(boolean useShortClassName) {
- this.useShortClassName = useShortClassName;
- }
-
- //---------------------------------------------------------------------
-
- /**
- * Gets whether to use the identity hash code.
- *
- * @return the current useIdentityHashCode flag
- */
- protected boolean isUseIdentityHashCode() {
- return useIdentityHashCode;
- }
-
- /**
- * Sets whether to use the identity hash code.
- *
- * @param useIdentityHashCode the new useIdentityHashCode flag
- */
- protected void setUseIdentityHashCode(boolean useIdentityHashCode) {
- this.useIdentityHashCode = useIdentityHashCode;
- }
-
- //---------------------------------------------------------------------
-
- /**
- * Gets whether to use the field names passed in.
- *
- * @return the current useFieldNames flag
- */
- protected boolean isUseFieldNames() {
- return useFieldNames;
- }
-
- /**
- * Sets whether to use the field names passed in.
- *
- * @param useFieldNames the new useFieldNames flag
- */
- protected void setUseFieldNames(boolean useFieldNames) {
- this.useFieldNames = useFieldNames;
- }
-
- //---------------------------------------------------------------------
-
- /**
- * Gets whether to use full detail when the caller doesn't
- * specify.
- *
- * @return the current defaultFullDetail flag
- */
- protected boolean isDefaultFullDetail() {
- return defaultFullDetail;
- }
-
- /**
- * Sets whether to use full detail when the caller doesn't
- * specify.
- *
- * @param defaultFullDetail the new defaultFullDetail flag
- */
- protected void setDefaultFullDetail(boolean defaultFullDetail) {
- this.defaultFullDetail = defaultFullDetail;
- }
-
- //---------------------------------------------------------------------
-
- /**
- * Gets whether to output array content detail.
- *
- * @return the current array content detail setting
- */
- protected boolean isArrayContentDetail() {
- return arrayContentDetail;
- }
-
- /**
- * Sets whether to output array content detail.
- *
- * @param arrayContentDetail the new arrayContentDetail flag
- */
- protected void setArrayContentDetail(boolean arrayContentDetail) {
- this.arrayContentDetail = arrayContentDetail;
- }
-
- //---------------------------------------------------------------------
-
- /**
- * Gets the array start text.
- *
- * @return the current array start text
- */
- protected String getArrayStart() {
- return arrayStart;
- }
-
- /**
- * Sets the array start text.
- *
- * null is accepted, but will be converted to
- * an empty String.
- *
- * @param arrayStart the new array start text
- */
- protected void setArrayStart(String arrayStart) {
- if (arrayStart == null) {
- arrayStart = "";
- }
- this.arrayStart = arrayStart;
- }
-
- //---------------------------------------------------------------------
-
- /**
- * Gets the array end text.
- *
- * @return the current array end text
- */
- protected String getArrayEnd() {
- return arrayEnd;
- }
-
- /**
- * Sets the array end text.
- *
- * null is accepted, but will be converted to
- * an empty String.
- *
- * @param arrayEnd the new array end text
- */
- protected void setArrayEnd(String arrayEnd) {
- if (arrayEnd == null) {
- arrayEnd = "";
- }
- this.arrayEnd = arrayEnd;
- }
-
- //---------------------------------------------------------------------
-
- /**
- * Gets the array separator text.
- *
- * @return the current array separator text
- */
- protected String getArraySeparator() {
- return arraySeparator;
- }
-
- /**
- * Sets the array separator text.
- *
- * null is accepted, but will be converted to
- * an empty String.
- *
- * @param arraySeparator the new array separator text
- */
- protected void setArraySeparator(String arraySeparator) {
- if (arraySeparator == null) {
- arraySeparator = "";
- }
- this.arraySeparator = arraySeparator;
- }
-
- //---------------------------------------------------------------------
-
- /**
- * Gets the content start text.
- *
- * @return the current content start text
- */
- protected String getContentStart() {
- return contentStart;
- }
-
- /**
- * Sets the content start text.
- *
- * null is accepted, but will be converted to
- * an empty String.
- *
- * @param contentStart the new content start text
- */
- protected void setContentStart(String contentStart) {
- if (contentStart == null) {
- contentStart = "";
- }
- this.contentStart = contentStart;
- }
-
- //---------------------------------------------------------------------
-
- /**
- * Gets the content end text.
- *
- * @return the current content end text
- */
- protected String getContentEnd() {
- return contentEnd;
- }
-
- /**
- * Sets the content end text.
- *
- * null is accepted, but will be converted to
- * an empty String.
- *
- * @param contentEnd the new content end text
- */
- protected void setContentEnd(String contentEnd) {
- if (contentEnd == null) {
- contentEnd = "";
- }
- this.contentEnd = contentEnd;
- }
-
- //---------------------------------------------------------------------
-
- /**
- * Gets the field name value separator text.
- *
- * @return the current field name value separator text
- */
- protected String getFieldNameValueSeparator() {
- return fieldNameValueSeparator;
- }
-
- /**
- * Sets the field name value separator text.
- *
- * null is accepted, but will be converted to
- * an empty String.
- *
- * @param fieldNameValueSeparator the new field name value separator text
- */
- protected void setFieldNameValueSeparator(String fieldNameValueSeparator) {
- if (fieldNameValueSeparator == null) {
- fieldNameValueSeparator = "";
- }
- this.fieldNameValueSeparator = fieldNameValueSeparator;
- }
-
- //---------------------------------------------------------------------
-
- /**
- * Gets the field separator text.
- *
- * @return the current field separator text
- */
- protected String getFieldSeparator() {
- return fieldSeparator;
- }
-
- /**
- * Sets the field separator text.
- *
- * null is accepted, but will be converted to
- * an empty String.
- *
- * @param fieldSeparator the new field separator text
- */
- protected void setFieldSeparator(String fieldSeparator) {
- if (fieldSeparator == null) {
- fieldSeparator = "";
- }
- this.fieldSeparator = fieldSeparator;
- }
-
- //---------------------------------------------------------------------
-
- /**
- * Gets whether the field separator should be added at the start
- * of each buffer.
- *
- * @return the fieldSeparatorAtStart flag
- * @since 2.0
- */
- protected boolean isFieldSeparatorAtStart() {
- return fieldSeparatorAtStart;
- }
-
- /**
- * Sets whether the field separator should be added at the start
- * of each buffer.
- *
- * @param fieldSeparatorAtStart the fieldSeparatorAtStart flag
- * @since 2.0
- */
- protected void setFieldSeparatorAtStart(boolean fieldSeparatorAtStart) {
- this.fieldSeparatorAtStart = fieldSeparatorAtStart;
- }
-
- //---------------------------------------------------------------------
-
- /**
- * Gets whether the field separator should be added at the end
- * of each buffer.
- *
- * @return fieldSeparatorAtEnd flag
- * @since 2.0
- */
- protected boolean isFieldSeparatorAtEnd() {
- return fieldSeparatorAtEnd;
- }
-
- /**
- * Sets whether the field separator should be added at the end
- * of each buffer.
- *
- * @param fieldSeparatorAtEnd the fieldSeparatorAtEnd flag
- * @since 2.0
- */
- protected void setFieldSeparatorAtEnd(boolean fieldSeparatorAtEnd) {
- this.fieldSeparatorAtEnd = fieldSeparatorAtEnd;
- }
-
- //---------------------------------------------------------------------
-
- /**
- * Gets the text to output when null found.
- *
- * @return the current text to output when null found
- */
- protected String getNullText() {
- return nullText;
- }
-
- /**
- * Sets the text to output when null found.
- *
- * null is accepted, but will be converted to
- * an empty String.
- *
- * @param nullText the new text to output when null found
- */
- protected void setNullText(String nullText) {
- if (nullText == null) {
- nullText = "";
- }
- this.nullText = nullText;
- }
-
- //---------------------------------------------------------------------
-
- /**
- * Gets the start text to output when a Collection,
- * Map or array size is output.
- *
- * This is output before the size value.
- *
- * @return the current start of size text
- */
- protected String getSizeStartText() {
- return sizeStartText;
- }
-
- /**
- * Sets the start text to output when a Collection,
- * Map or array size is output.
- *
- * This is output before the size value.
- *
- * null is accepted, but will be converted to
- * an empty String.
- *
- * @param sizeStartText the new start of size text
- */
- protected void setSizeStartText(String sizeStartText) {
- if (sizeStartText == null) {
- sizeStartText = "";
- }
- this.sizeStartText = sizeStartText;
- }
-
- //---------------------------------------------------------------------
-
- /**
- * Gets the end text to output when a Collection,
- * Map or array size is output.
- *
- * This is output after the size value.
- *
- * @return the current end of size text
- */
- protected String getSizeEndText() {
- return sizeEndText;
- }
-
- /**
- * Sets the end text to output when a Collection,
- * Map or array size is output.
- *
- * This is output after the size value.
- *
- * null is accepted, but will be converted to
- * an empty String.
- *
- * @param sizeEndText the new end of size text
- */
- protected void setSizeEndText(String sizeEndText) {
- if (sizeEndText == null) {
- sizeEndText = "";
- }
- this.sizeEndText = sizeEndText;
- }
-
- //---------------------------------------------------------------------
-
- /**
- * Gets the start text to output when an Object is
- * output in summary mode.
- *
- * This is output before the size value.
- *
- * @return the current start of summary text
- */
- protected String getSummaryObjectStartText() {
- return summaryObjectStartText;
- }
-
- /**
- * Sets the start text to output when an Object is
- * output in summary mode.
- *
- * This is output before the size value.
- *
- * null is accepted, but will be converted to
- * an empty String.
- *
- * @param summaryObjectStartText the new start of summary text
- */
- protected void setSummaryObjectStartText(String summaryObjectStartText) {
- if (summaryObjectStartText == null) {
- summaryObjectStartText = "";
- }
- this.summaryObjectStartText = summaryObjectStartText;
- }
-
- //---------------------------------------------------------------------
-
- /**
- * Gets the end text to output when an Object is
- * output in summary mode.
- *
- * This is output after the size value.
- *
- * @return the current end of summary text
- */
- protected String getSummaryObjectEndText() {
- return summaryObjectEndText;
- }
-
- /**
- * Sets the end text to output when an Object is
- * output in summary mode.
- *
- * This is output after the size value.
- *
- * null is accepted, but will be converted to
- * an empty String.
- *
- * @param summaryObjectEndText the new end of summary text
- */
- protected void setSummaryObjectEndText(String summaryObjectEndText) {
- if (summaryObjectEndText == null) {
- summaryObjectEndText = "";
- }
- this.summaryObjectEndText = summaryObjectEndText;
- }
-
- //----------------------------------------------------------------------------
-
- /**
- * Default ToStringStyle.
- *
- * This is an inner class rather than using
- * StandardToStringStyle to ensure its immutability.
- */
- private static final class DefaultToStringStyle extends ToStringStyle {
-
- /**
- * Required for serialization support.
- *
- * @see java.io.Serializable
- */
- private static final long serialVersionUID = 1L;
-
- /**
- * Constructor.
- *
- * Use the static constant rather than instantiating.
- */
- DefaultToStringStyle() {
- super();
- }
-
- /**
- * Ensure Singleton after serialization.
- *
- * @return the singleton
- */
- private Object readResolve() {
- return ToStringStyle.DEFAULT_STYLE;
- }
-
- }
-
- //----------------------------------------------------------------------------
-
- /**
- * ToStringStyle that does not print out
- * the field names.
- *
- * This is an inner class rather than using
- * StandardToStringStyle to ensure its immutability.
- */
- private static final class NoFieldNameToStringStyle extends ToStringStyle {
-
- private static final long serialVersionUID = 1L;
-
- /**
- *
Constructor.
- *
- * Use the static constant rather than instantiating.
- */
- NoFieldNameToStringStyle() {
- super();
- this.setUseFieldNames(false);
- }
-
- /**
- * Ensure Singleton after serialization.
- *
- * @return the singleton
- */
- private Object readResolve() {
- return ToStringStyle.NO_FIELD_NAMES_STYLE;
- }
-
- }
-
- //----------------------------------------------------------------------------
-
- /**
- * ToStringStyle that prints out the short
- * class name and no identity hashcode.
- *
- * This is an inner class rather than using
- * StandardToStringStyle to ensure its immutability.
- */
- private static final class ShortPrefixToStringStyle extends ToStringStyle {
-
- private static final long serialVersionUID = 1L;
-
- /**
- * Constructor.
- *
- * Use the static constant rather than instantiating.
- */
- ShortPrefixToStringStyle() {
- super();
- this.setUseShortClassName(true);
- this.setUseIdentityHashCode(false);
- }
-
- /**
- * Ensure Singleton after serialization.
- * @return the singleton
- */
- private Object readResolve() {
- return ToStringStyle.SHORT_PREFIX_STYLE;
- }
-
- }
-
- /**
- * ToStringStyle that does not print out the
- * classname, identity hashcode, content start or field name.
- *
- * This is an inner class rather than using
- * StandardToStringStyle to ensure its immutability.
- */
- private static final class SimpleToStringStyle extends ToStringStyle {
-
- private static final long serialVersionUID = 1L;
-
- /**
- * Constructor.
- *
- * Use the static constant rather than instantiating.
- */
- SimpleToStringStyle() {
- super();
- this.setUseClassName(false);
- this.setUseIdentityHashCode(false);
- this.setUseFieldNames(false);
- this.setContentStart("");
- this.setContentEnd("");
- }
-
- /**
- * Ensure Singleton after serialization.
- * @return the singleton
- */
- private Object readResolve() {
- return ToStringStyle.SIMPLE_STYLE;
- }
-
- }
-
- //----------------------------------------------------------------------------
-
- /**
- * ToStringStyle that outputs on multiple lines.
- *
- * This is an inner class rather than using
- * StandardToStringStyle to ensure its immutability.
- */
- private static final class MultiLineToStringStyle extends ToStringStyle {
-
- private static final long serialVersionUID = 1L;
-
- /**
- * Constructor.
- *
- * Use the static constant rather than instantiating.
- */
- MultiLineToStringStyle() {
- super();
- this.setContentStart("[");
- this.setFieldSeparator(SystemUtils.LINE_SEPARATOR + " ");
- this.setFieldSeparatorAtStart(true);
- this.setContentEnd(SystemUtils.LINE_SEPARATOR + "]");
- }
-
- /**
- * Ensure Singleton after serialization.
- *
- * @return the singleton
- */
- private Object readResolve() {
- return ToStringStyle.MULTI_LINE_STYLE;
- }
-
- }
-
-}
diff --git a/core/src/main/java/external/org/apache/commons/lang3/builder/package.html b/core/src/main/java/external/org/apache/commons/lang3/builder/package.html
deleted file mode 100644
index dd40682d..00000000
--- a/core/src/main/java/external/org/apache/commons/lang3/builder/package.html
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-Assists in creating consistent equals(Object), toString(),
-hashCode(), and compareTo(Object) methods.
-@see java.lang.Object#equals(Object)
-@see java.lang.Object#toString()
-@see java.lang.Object#hashCode()
-@see java.lang.Comparable#compareTo(Object)
-@since 1.0
-These classes are not thread-safe.
-
-
diff --git a/core/src/main/java/external/org/apache/commons/lang3/exception/CloneFailedException.java b/core/src/main/java/external/org/apache/commons/lang3/exception/CloneFailedException.java
deleted file mode 100644
index edd2d775..00000000
--- a/core/src/main/java/external/org/apache/commons/lang3/exception/CloneFailedException.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package external.org.apache.commons.lang3.exception;
-
-/**
- * Exception thrown when a clone cannot be created. In contrast to
- * {@link CloneNotSupportedException} this is a {@link RuntimeException}.
- *
- * @since 3.0
- */
-public class CloneFailedException extends RuntimeException {
- // ~ Static fields/initializers ---------------------------------------------
-
- private static final long serialVersionUID = 20091223L;
-
- // ~ Constructors -----------------------------------------------------------
-
- /**
- * Constructs a CloneFailedException.
- *
- * @param message description of the exception
- * @since upcoming
- */
- public CloneFailedException(final String message) {
- super(message);
- }
-
- /**
- * Constructs a CloneFailedException.
- *
- * @param cause cause of the exception
- * @since upcoming
- */
- public CloneFailedException(final Throwable cause) {
- super(cause);
- }
-
- /**
- * Constructs a CloneFailedException.
- *
- * @param message description of the exception
- * @param cause cause of the exception
- * @since upcoming
- */
- public CloneFailedException(final String message, final Throwable cause) {
- super(message, cause);
- }
-}
diff --git a/core/src/main/java/external/org/apache/commons/lang3/exception/package.html b/core/src/main/java/external/org/apache/commons/lang3/exception/package.html
deleted file mode 100644
index b9d94036..00000000
--- a/core/src/main/java/external/org/apache/commons/lang3/exception/package.html
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-
-Provides functionality for Exceptions.
-Contains the concept of an exception with context i.e. such an exception
-will contain a map with keys and values. This provides an easy way to pass valuable
-state information at exception time in useful form to a calling process.
-Lastly, {@link org.apache.commons.lang3.exception.ExceptionUtils}
-also contains Throwable manipulation and examination routines.
-@since 1.0
-
-
diff --git a/core/src/main/java/external/org/apache/commons/lang3/mutable/Mutable.java b/core/src/main/java/external/org/apache/commons/lang3/mutable/Mutable.java
deleted file mode 100644
index aa733e50..00000000
--- a/core/src/main/java/external/org/apache/commons/lang3/mutable/Mutable.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package external.org.apache.commons.lang3.mutable;
-
-/**
- * Provides mutable access to a value.
- *
- * Mutable is used as a generic interface to the implementations in this package.
- *
- * A typical use case would be to enable a primitive or string to be passed to a method and allow that method to
- * effectively change the value of the primitive/string. Another use case is to store a frequently changing primitive in
- * a collection (for example a total in a map) without needing to create new Integer/Long wrapper objects.
- *
- * @since 2.1
- * @param the type to set and get
- * @version $Id: Mutable.java 1153213 2011-08-02 17:35:39Z ggregory $
- */
-public interface Mutable {
-
- /**
- * Gets the value of this mutable.
- *
- * @return the stored value
- */
- T getValue();
-
- /**
- * Sets the value of this mutable.
- *
- * @param value
- * the value to store
- * @throws NullPointerException
- * if the object is null and null is invalid
- * @throws ClassCastException
- * if the type is invalid
- */
- void setValue(T value);
-
-}
diff --git a/core/src/main/java/external/org/apache/commons/lang3/mutable/MutableInt.java b/core/src/main/java/external/org/apache/commons/lang3/mutable/MutableInt.java
deleted file mode 100644
index d7e83d9b..00000000
--- a/core/src/main/java/external/org/apache/commons/lang3/mutable/MutableInt.java
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package external.org.apache.commons.lang3.mutable;
-
-/**
- * A mutable int wrapper.
- *
- * Note that as MutableInt does not extend Integer, it is not treated by String.format as an Integer parameter.
- *
- * @see Integer
- * @since 2.1
- * @version $Id: MutableInt.java 1160571 2011-08-23 07:36:08Z bayard $
- */
-public class MutableInt extends Number implements Comparable, Mutable {
-
- /**
- * Required for serialization support.
- *
- * @see java.io.Serializable
- */
- private static final long serialVersionUID = 512176391864L;
-
- /** The mutable value. */
- private int value;
-
- /**
- * Constructs a new MutableInt with the default value of zero.
- */
- public MutableInt() {
- super();
- }
-
- /**
- * Constructs a new MutableInt with the specified value.
- *
- * @param value the initial value to store
- */
- public MutableInt(int value) {
- super();
- this.value = value;
- }
-
- /**
- * Constructs a new MutableInt with the specified value.
- *
- * @param value the initial value to store, not null
- * @throws NullPointerException if the object is null
- */
- public MutableInt(Number value) {
- super();
- this.value = value.intValue();
- }
-
- /**
- * Constructs a new MutableInt parsing the given string.
- *
- * @param value the string to parse, not null
- * @throws NumberFormatException if the string cannot be parsed into an int
- * @since 2.5
- */
- public MutableInt(String value) throws NumberFormatException {
- super();
- this.value = Integer.parseInt(value);
- }
-
- //-----------------------------------------------------------------------
- /**
- * Gets the value as a Integer instance.
- *
- * @return the value as a Integer, never null
- */
- public Integer getValue() {
- return Integer.valueOf(this.value);
- }
-
- /**
- * Sets the value.
- *
- * @param value the value to set
- */
- public void setValue(int value) {
- this.value = value;
- }
-
- /**
- * Sets the value from any Number instance.
- *
- * @param value the value to set, not null
- * @throws NullPointerException if the object is null
- */
- public void setValue(Number value) {
- this.value = value.intValue();
- }
-
- //-----------------------------------------------------------------------
- /**
- * Increments the value.
- *
- * @since Commons Lang 2.2
- */
- public void increment() {
- value++;
- }
-
- /**
- * Decrements the value.
- *
- * @since Commons Lang 2.2
- */
- public void decrement() {
- value--;
- }
-
- //-----------------------------------------------------------------------
- /**
- * Adds a value to the value of this instance.
- *
- * @param operand the value to add, not null
- * @since Commons Lang 2.2
- */
- public void add(int operand) {
- this.value += operand;
- }
-
- /**
- * Adds a value to the value of this instance.
- *
- * @param operand the value to add, not null
- * @throws NullPointerException if the object is null
- * @since Commons Lang 2.2
- */
- public void add(Number operand) {
- this.value += operand.intValue();
- }
-
- /**
- * Subtracts a value from the value of this instance.
- *
- * @param operand the value to subtract, not null
- * @since Commons Lang 2.2
- */
- public void subtract(int operand) {
- this.value -= operand;
- }
-
- /**
- * Subtracts a value from the value of this instance.
- *
- * @param operand the value to subtract, not null
- * @throws NullPointerException if the object is null
- * @since Commons Lang 2.2
- */
- public void subtract(Number operand) {
- this.value -= operand.intValue();
- }
-
- //-----------------------------------------------------------------------
- // shortValue and byteValue rely on Number implementation
- /**
- * Returns the value of this MutableInt as an int.
- *
- * @return the numeric value represented by this object after conversion to type int.
- */
- @Override
- public int intValue() {
- return value;
- }
-
- /**
- * Returns the value of this MutableInt as a long.
- *
- * @return the numeric value represented by this object after conversion to type long.
- */
- @Override
- public long longValue() {
- return value;
- }
-
- /**
- * Returns the value of this MutableInt as a float.
- *
- * @return the numeric value represented by this object after conversion to type float.
- */
- @Override
- public float floatValue() {
- return value;
- }
-
- /**
- * Returns the value of this MutableInt as a double.
- *
- * @return the numeric value represented by this object after conversion to type double.
- */
- @Override
- public double doubleValue() {
- return value;
- }
-
- //-----------------------------------------------------------------------
- /**
- * Gets this mutable as an instance of Integer.
- *
- * @return a Integer instance containing the value from this mutable, never null
- */
- public Integer toInteger() {
- return Integer.valueOf(intValue());
- }
-
- //-----------------------------------------------------------------------
- /**
- * Compares this object to the specified object. The result is true if and only if the argument is
- * not null and is a MutableInt object that contains the same int value
- * as this object.
- *
- * @param obj the object to compare with, null returns false
- * @return true if the objects are the same; false otherwise.
- */
- @Override
- public boolean equals(Object obj) {
- if (obj instanceof MutableInt) {
- return value == ((MutableInt) obj).intValue();
- }
- return false;
- }
-
- /**
- * Returns a suitable hash code for this mutable.
- *
- * @return a suitable hash code
- */
- @Override
- public int hashCode() {
- return value;
- }
-
- //-----------------------------------------------------------------------
- /**
- * Compares this mutable to another in ascending order.
- *
- * @param other the other mutable to compare to, not null
- * @return negative if this is less, zero if equal, positive if greater
- */
- public int compareTo(MutableInt other) {
- int anotherVal = other.value;
- return value < anotherVal ? -1 : (value == anotherVal ? 0 : 1);
- }
-
- //-----------------------------------------------------------------------
- /**
- * Returns the String value of this mutable.
- *
- * @return the mutable value as a string
- */
- @Override
- public String toString() {
- return String.valueOf(value);
- }
-
-}
diff --git a/core/src/main/java/external/org/apache/commons/lang3/mutable/package.html b/core/src/main/java/external/org/apache/commons/lang3/mutable/package.html
deleted file mode 100644
index 2f7436af..00000000
--- a/core/src/main/java/external/org/apache/commons/lang3/mutable/package.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-Provides typed mutable wrappers to primitive values and Object.
-@since 2.1
-These classes are not thread-safe.
-
-
diff --git a/core/src/main/java/external/org/apache/commons/lang3/overview.html b/core/src/main/java/external/org/apache/commons/lang3/overview.html
deleted file mode 100644
index f8433aae..00000000
--- a/core/src/main/java/external/org/apache/commons/lang3/overview.html
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-
-
-This document is the API specification for the Apache Commons Lang library.
-
-
-
diff --git a/core/src/main/java/external/org/apache/commons/lang3/package.html b/core/src/main/java/external/org/apache/commons/lang3/package.html
deleted file mode 100644
index 1625c62d..00000000
--- a/core/src/main/java/external/org/apache/commons/lang3/package.html
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
-
-Provides highly reusable static utility methods, chiefly concerned
-with adding value to the {@link java.lang} classes.
-@since 1.0
-Most of these classes are immutable and thus thread-safe.
-However Charset is not currently guaranteed thread-safe under all circumstances.
-
-
diff --git a/core/src/main/java/external/org/apache/commons/lang3/reflect/MemberUtils.java b/core/src/main/java/external/org/apache/commons/lang3/reflect/MemberUtils.java
deleted file mode 100644
index c268fd76..00000000
--- a/core/src/main/java/external/org/apache/commons/lang3/reflect/MemberUtils.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package external.org.apache.commons.lang3.reflect;
-
-import java.lang.reflect.AccessibleObject;
-import java.lang.reflect.Member;
-import java.lang.reflect.Modifier;
-
-import external.org.apache.commons.lang3.ClassUtils;
-
-/**
- * Contains common code for working with Methods/Constructors, extracted and
- * refactored from MethodUtils when it was imported from Commons
- * BeanUtils.
- *
- * @since 2.5
- * @version $Id: MemberUtils.java 1143537 2011-07-06 19:30:22Z joehni $
- */
-public abstract class MemberUtils {
- // TODO extract an interface to implement compareParameterSets(...)?
-
- private static final int ACCESS_TEST = Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE;
-
- /** Array of primitive number types ordered by "promotability" */
- private static final Class>[] ORDERED_PRIMITIVE_TYPES = { Byte.TYPE, Short.TYPE,
- Character.TYPE, Integer.TYPE, Long.TYPE, Float.TYPE, Double.TYPE };
-
- /**
- * XXX Default access superclass workaround
- *
- * When a public class has a default access superclass with public members,
- * these members are accessible. Calling them from compiled code works fine.
- * Unfortunately, on some JVMs, using reflection to invoke these members
- * seems to (wrongly) prevent access even when the modifier is public.
- * Calling setAccessible(true) solves the problem but will only work from
- * sufficiently privileged code. Better workarounds would be gratefully
- * accepted.
- * @param o the AccessibleObject to set as accessible
- */
- static void setAccessibleWorkaround(AccessibleObject o) {
- if (o == null || o.isAccessible()) {
- return;
- }
- Member m = (Member) o;
- if (Modifier.isPublic(m.getModifiers())
- && isPackageAccess(m.getDeclaringClass().getModifiers())) {
- try {
- o.setAccessible(true);
- } catch (SecurityException e) { // NOPMD
- // ignore in favor of subsequent IllegalAccessException
- }
- }
- }
-
- /**
- * Returns whether a given set of modifiers implies package access.
- * @param modifiers to test
- * @return true unless package/protected/private modifier detected
- */
- static boolean isPackageAccess(int modifiers) {
- return (modifiers & ACCESS_TEST) == 0;
- }
-
- /**
- * Returns whether a Member is accessible.
- * @param m Member to check
- * @return true if m is accessible
- */
- static boolean isAccessible(Member m) {
- return m != null && Modifier.isPublic(m.getModifiers()) && !m.isSynthetic();
- }
-
- /**
- * Compares the relative fitness of two sets of parameter types in terms of
- * matching a third set of runtime parameter types, such that a list ordered
- * by the results of the comparison would return the best match first
- * (least).
- *
- * @param left the "left" parameter set
- * @param right the "right" parameter set
- * @param actual the runtime parameter types to match against
- * left/right
- * @return int consistent with compare semantics
- */
- public static int compareParameterTypes(Class>[] left, Class>[] right, Class>[] actual) {
- float leftCost = getTotalTransformationCost(actual, left);
- float rightCost = getTotalTransformationCost(actual, right);
- return leftCost < rightCost ? -1 : rightCost < leftCost ? 1 : 0;
- }
-
- /**
- * Returns the sum of the object transformation cost for each class in the
- * source argument list.
- * @param srcArgs The source arguments
- * @param destArgs The destination arguments
- * @return The total transformation cost
- */
- private static float getTotalTransformationCost(Class>[] srcArgs, Class>[] destArgs) {
- float totalCost = 0.0f;
- for (int i = 0; i < srcArgs.length; i++) {
- Class> srcClass, destClass;
- srcClass = srcArgs[i];
- destClass = destArgs[i];
- totalCost += getObjectTransformationCost(srcClass, destClass);
- }
- return totalCost;
- }
-
- /**
- * Gets the number of steps required needed to turn the source class into
- * the destination class. This represents the number of steps in the object
- * hierarchy graph.
- * @param srcClass The source class
- * @param destClass The destination class
- * @return The cost of transforming an object
- */
- private static float getObjectTransformationCost(Class> srcClass, Class> destClass) {
- if (destClass.isPrimitive()) {
- return getPrimitivePromotionCost(srcClass, destClass);
- }
- float cost = 0.0f;
- while (srcClass != null && !destClass.equals(srcClass)) {
- if (destClass.isInterface() && ClassUtils.isAssignable(srcClass, destClass)) {
- // slight penalty for interface match.
- // we still want an exact match to override an interface match,
- // but
- // an interface match should override anything where we have to
- // get a superclass.
- cost += 0.25f;
- break;
- }
- cost++;
- srcClass = srcClass.getSuperclass();
- }
- /*
- * If the destination class is null, we've travelled all the way up to
- * an Object match. We'll penalize this by adding 1.5 to the cost.
- */
- if (srcClass == null) {
- cost += 1.5f;
- }
- return cost;
- }
-
- /**
- * Gets the number of steps required to promote a primitive number to another
- * type.
- * @param srcClass the (primitive) source class
- * @param destClass the (primitive) destination class
- * @return The cost of promoting the primitive
- */
- private static float getPrimitivePromotionCost(final Class> srcClass, final Class> destClass) {
- float cost = 0.0f;
- Class> cls = srcClass;
- if (!cls.isPrimitive()) {
- // slight unwrapping penalty
- cost += 0.1f;
- cls = ClassUtils.wrapperToPrimitive(cls);
- }
- for (int i = 0; cls != destClass && i < ORDERED_PRIMITIVE_TYPES.length; i++) {
- if (cls == ORDERED_PRIMITIVE_TYPES[i]) {
- cost += 0.1f;
- if (i < ORDERED_PRIMITIVE_TYPES.length - 1) {
- cls = ORDERED_PRIMITIVE_TYPES[i + 1];
- }
- }
- }
- return cost;
- }
-
-}
diff --git a/core/src/main/java/external/org/apache/commons/lang3/reflect/MethodUtils.java b/core/src/main/java/external/org/apache/commons/lang3/reflect/MethodUtils.java
deleted file mode 100644
index d72a1ebe..00000000
--- a/core/src/main/java/external/org/apache/commons/lang3/reflect/MethodUtils.java
+++ /dev/null
@@ -1,537 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package external.org.apache.commons.lang3.reflect;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-
-import external.org.apache.commons.lang3.ArrayUtils;
-import external.org.apache.commons.lang3.ClassUtils;
-
-/**
- * Utility reflection methods focused on methods, originally from Commons BeanUtils.
- * Differences from the BeanUtils version may be noted, especially where similar functionality
- * already existed within Lang.
- *
- *
- * Known Limitations
- * Accessing Public Methods In A Default Access Superclass
- * There is an issue when invoking public methods contained in a default access superclass on JREs prior to 1.4.
- * Reflection locates these methods fine and correctly assigns them as public.
- * However, an IllegalAccessException is thrown if the method is invoked.
- *
- * MethodUtils contains a workaround for this situation.
- * It will attempt to call setAccessible on this method.
- * If this call succeeds, then the method can be invoked as normal.
- * This call will only succeed when the application has sufficient security privileges.
- * If this call fails then the method may fail.
- *
- * @since 2.5
- * @version $Id: MethodUtils.java 1166253 2011-09-07 16:27:42Z ggregory $
- */
-public class MethodUtils {
-
- /**
- * MethodUtils instances should NOT be constructed in standard programming.
- * Instead, the class should be used as
- * MethodUtils.getAccessibleMethod(method).
- *
- * This constructor is public to permit tools that require a JavaBean
- * instance to operate.
- */
- public MethodUtils() {
- super();
- }
-
- /**
- * Invokes a named method whose parameter type matches the object type.
- *
- * This method delegates the method search to {@link #getMatchingAccessibleMethod(Class, String, Class[])}.
- *
- * This method supports calls to methods taking primitive parameters
- * via passing in wrapping classes. So, for example, a Boolean object
- * would match a boolean primitive.
- *
- * This is a convenient wrapper for
- * {@link #invokeMethod(Object object,String methodName, Object[] args, Class[] parameterTypes)}.
- *
- *
- * @param object invoke method on this object
- * @param methodName get method with this name
- * @param args use these arguments - treat null as empty array
- * @return The value returned by the invoked method
- *
- * @throws NoSuchMethodException if there is no such accessible method
- * @throws InvocationTargetException wraps an exception thrown by the method invoked
- * @throws IllegalAccessException if the requested method is not accessible via reflection
- */
- public static Object invokeMethod(Object object, String methodName,
- Object... args) throws NoSuchMethodException,
- IllegalAccessException, InvocationTargetException {
- if (args == null) {
- args = ArrayUtils.EMPTY_OBJECT_ARRAY;
- }
- int arguments = args.length;
- Class>[] parameterTypes = new Class[arguments];
- for (int i = 0; i < arguments; i++) {
- parameterTypes[i] = args[i].getClass();
- }
- return invokeMethod(object, methodName, args, parameterTypes);
- }
-
- /**
- * Invokes a named method whose parameter type matches the object type.
- *
- * This method delegates the method search to {@link #getMatchingAccessibleMethod(Class, String, Class[])}.
- *
- * This method supports calls to methods taking primitive parameters
- * via passing in wrapping classes. So, for example, a Boolean object
- * would match a boolean primitive.
- *
- * @param object invoke method on this object
- * @param methodName get method with this name
- * @param args use these arguments - treat null as empty array
- * @param parameterTypes match these parameters - treat null as empty array
- * @return The value returned by the invoked method
- *
- * @throws NoSuchMethodException if there is no such accessible method
- * @throws InvocationTargetException wraps an exception thrown by the method invoked
- * @throws IllegalAccessException if the requested method is not accessible via reflection
- */
- public static Object invokeMethod(Object object, String methodName,
- Object[] args, Class>[] parameterTypes)
- throws NoSuchMethodException, IllegalAccessException,
- InvocationTargetException {
- if (parameterTypes == null) {
- parameterTypes = ArrayUtils.EMPTY_CLASS_ARRAY;
- }
- if (args == null) {
- args = ArrayUtils.EMPTY_OBJECT_ARRAY;
- }
- Method method = getMatchingAccessibleMethod(object.getClass(),
- methodName, parameterTypes);
- if (method == null) {
- throw new NoSuchMethodException("No such accessible method: "
- + methodName + "() on object: "
- + object.getClass().getName());
- }
- return method.invoke(object, args);
- }
-
- /**
- * Invokes a method whose parameter types match exactly the object
- * types.
- *
- * This uses reflection to invoke the method obtained from a call to
- * getAccessibleMethod().
- *
- * @param object invoke method on this object
- * @param methodName get method with this name
- * @param args use these arguments - treat null as empty array
- * @return The value returned by the invoked method
- *
- * @throws NoSuchMethodException if there is no such accessible method
- * @throws InvocationTargetException wraps an exception thrown by the
- * method invoked
- * @throws IllegalAccessException if the requested method is not accessible
- * via reflection
- */
- public static Object invokeExactMethod(Object object, String methodName,
- Object... args) throws NoSuchMethodException,
- IllegalAccessException, InvocationTargetException {
- if (args == null) {
- args = ArrayUtils.EMPTY_OBJECT_ARRAY;
- }
- int arguments = args.length;
- Class>[] parameterTypes = new Class[arguments];
- for (int i = 0; i < arguments; i++) {
- parameterTypes[i] = args[i].getClass();
- }
- return invokeExactMethod(object, methodName, args, parameterTypes);
- }
-
- /**
- * Invokes a method whose parameter types match exactly the parameter
- * types given.
- *
- * This uses reflection to invoke the method obtained from a call to
- * getAccessibleMethod().
- *
- * @param object invoke method on this object
- * @param methodName get method with this name
- * @param args use these arguments - treat null as empty array
- * @param parameterTypes match these parameters - treat null as empty array
- * @return The value returned by the invoked method
- *
- * @throws NoSuchMethodException if there is no such accessible method
- * @throws InvocationTargetException wraps an exception thrown by the
- * method invoked
- * @throws IllegalAccessException if the requested method is not accessible
- * via reflection
- */
- public static Object invokeExactMethod(Object object, String methodName,
- Object[] args, Class>[] parameterTypes)
- throws NoSuchMethodException, IllegalAccessException,
- InvocationTargetException {
- if (args == null) {
- args = ArrayUtils.EMPTY_OBJECT_ARRAY;
- }
- if (parameterTypes == null) {
- parameterTypes = ArrayUtils.EMPTY_CLASS_ARRAY;
- }
- Method method = getAccessibleMethod(object.getClass(), methodName,
- parameterTypes);
- if (method == null) {
- throw new NoSuchMethodException("No such accessible method: "
- + methodName + "() on object: "
- + object.getClass().getName());
- }
- return method.invoke(object, args);
- }
-
- /**
- * Invokes a static method whose parameter types match exactly the parameter
- * types given.
- *
- * This uses reflection to invoke the method obtained from a call to
- * {@link #getAccessibleMethod(Class, String, Class[])}.
- *
- * @param cls invoke static method on this class
- * @param methodName get method with this name
- * @param args use these arguments - treat null as empty array
- * @param parameterTypes match these parameters - treat null as empty array
- * @return The value returned by the invoked method
- *
- * @throws NoSuchMethodException if there is no such accessible method
- * @throws InvocationTargetException wraps an exception thrown by the
- * method invoked
- * @throws IllegalAccessException if the requested method is not accessible
- * via reflection
- */
- public static Object invokeExactStaticMethod(Class> cls, String methodName,
- Object[] args, Class>[] parameterTypes)
- throws NoSuchMethodException, IllegalAccessException,
- InvocationTargetException {
- if (args == null) {
- args = ArrayUtils.EMPTY_OBJECT_ARRAY;
- }
- if (parameterTypes == null) {
- parameterTypes = ArrayUtils.EMPTY_CLASS_ARRAY;
- }
- Method method = getAccessibleMethod(cls, methodName, parameterTypes);
- if (method == null) {
- throw new NoSuchMethodException("No such accessible method: "
- + methodName + "() on class: " + cls.getName());
- }
- return method.invoke(null, args);
- }
-
- /**
- * Invokes a named static method whose parameter type matches the object type.
- *
- * This method delegates the method search to {@link #getMatchingAccessibleMethod(Class, String, Class[])}.
- *
- * This method supports calls to methods taking primitive parameters
- * via passing in wrapping classes. So, for example, a Boolean class
- * would match a boolean primitive.
- *
- * This is a convenient wrapper for
- * {@link #invokeStaticMethod(Class objectClass,String methodName,Object [] args,Class[] parameterTypes)}.
- *
- *
- * @param cls invoke static method on this class
- * @param methodName get method with this name
- * @param args use these arguments - treat null as empty array
- * @return The value returned by the invoked method
- *
- * @throws NoSuchMethodException if there is no such accessible method
- * @throws InvocationTargetException wraps an exception thrown by the
- * method invoked
- * @throws IllegalAccessException if the requested method is not accessible
- * via reflection
- */
- public static Object invokeStaticMethod(Class> cls, String methodName,
- Object... args) throws NoSuchMethodException,
- IllegalAccessException, InvocationTargetException {
- if (args == null) {
- args = ArrayUtils.EMPTY_OBJECT_ARRAY;
- }
- int arguments = args.length;
- Class>[] parameterTypes = new Class[arguments];
- for (int i = 0; i < arguments; i++) {
- parameterTypes[i] = args[i].getClass();
- }
- return invokeStaticMethod(cls, methodName, args, parameterTypes);
- }
-
- /**
- * Invokes a named static method whose parameter type matches the object type.
- *
- * This method delegates the method search to {@link #getMatchingAccessibleMethod(Class, String, Class[])}.
- *
- * This method supports calls to methods taking primitive parameters
- * via passing in wrapping classes. So, for example, a Boolean class
- * would match a boolean primitive.
- *
- *
- * @param cls invoke static method on this class
- * @param methodName get method with this name
- * @param args use these arguments - treat null as empty array
- * @param parameterTypes match these parameters - treat null as empty array
- * @return The value returned by the invoked method
- *
- * @throws NoSuchMethodException if there is no such accessible method
- * @throws InvocationTargetException wraps an exception thrown by the
- * method invoked
- * @throws IllegalAccessException if the requested method is not accessible
- * via reflection
- */
- public static Object invokeStaticMethod(Class> cls, String methodName,
- Object[] args, Class>[] parameterTypes)
- throws NoSuchMethodException, IllegalAccessException,
- InvocationTargetException {
- if (parameterTypes == null) {
- parameterTypes = ArrayUtils.EMPTY_CLASS_ARRAY;
- }
- if (args == null) {
- args = ArrayUtils.EMPTY_OBJECT_ARRAY;
- }
- Method method = getMatchingAccessibleMethod(cls, methodName,
- parameterTypes);
- if (method == null) {
- throw new NoSuchMethodException("No such accessible method: "
- + methodName + "() on class: " + cls.getName());
- }
- return method.invoke(null, args);
- }
-
- /**
- * Invokes a static method whose parameter types match exactly the object
- * types.
- *
- * This uses reflection to invoke the method obtained from a call to
- * {@link #getAccessibleMethod(Class, String, Class[])}.
- *
- * @param cls invoke static method on this class
- * @param methodName get method with this name
- * @param args use these arguments - treat null as empty array
- * @return The value returned by the invoked method
- *
- * @throws NoSuchMethodException if there is no such accessible method
- * @throws InvocationTargetException wraps an exception thrown by the
- * method invoked
- * @throws IllegalAccessException if the requested method is not accessible
- * via reflection
- */
- public static Object invokeExactStaticMethod(Class> cls, String methodName,
- Object... args) throws NoSuchMethodException,
- IllegalAccessException, InvocationTargetException {
- if (args == null) {
- args = ArrayUtils.EMPTY_OBJECT_ARRAY;
- }
- int arguments = args.length;
- Class>[] parameterTypes = new Class[arguments];
- for (int i = 0; i < arguments; i++) {
- parameterTypes[i] = args[i].getClass();
- }
- return invokeExactStaticMethod(cls, methodName, args, parameterTypes);
- }
-
- /**
- * Returns an accessible method (that is, one that can be invoked via
- * reflection) with given name and parameters. If no such method
- * can be found, return null.
- * This is just a convenient wrapper for
- * {@link #getAccessibleMethod(Method method)}.
- *
- * @param cls get method from this class
- * @param methodName get method with this name
- * @param parameterTypes with these parameters types
- * @return The accessible method
- */
- public static Method getAccessibleMethod(Class> cls, String methodName,
- Class>... parameterTypes) {
- try {
- return getAccessibleMethod(cls.getMethod(methodName,
- parameterTypes));
- } catch (NoSuchMethodException e) {
- return null;
- }
- }
-
- /**
- * Returns an accessible method (that is, one that can be invoked via
- * reflection) that implements the specified Method. If no such method
- * can be found, return null.
- *
- * @param method The method that we wish to call
- * @return The accessible method
- */
- public static Method getAccessibleMethod(Method method) {
- if (!MemberUtils.isAccessible(method)) {
- return null;
- }
- // If the declaring class is public, we are done
- Class> cls = method.getDeclaringClass();
- if (Modifier.isPublic(cls.getModifiers())) {
- return method;
- }
- String methodName = method.getName();
- Class>[] parameterTypes = method.getParameterTypes();
-
- // Check the implemented interfaces and subinterfaces
- method = getAccessibleMethodFromInterfaceNest(cls, methodName,
- parameterTypes);
-
- // Check the superclass chain
- if (method == null) {
- method = getAccessibleMethodFromSuperclass(cls, methodName,
- parameterTypes);
- }
- return method;
- }
-
- /**
- * Returns an accessible method (that is, one that can be invoked via
- * reflection) by scanning through the superclasses. If no such method
- * can be found, return null.
- *
- * @param cls Class to be checked
- * @param methodName Method name of the method we wish to call
- * @param parameterTypes The parameter type signatures
- * @return the accessible method or null if not found
- */
- private static Method getAccessibleMethodFromSuperclass(Class> cls,
- String methodName, Class>... parameterTypes) {
- Class> parentClass = cls.getSuperclass();
- while (parentClass != null) {
- if (Modifier.isPublic(parentClass.getModifiers())) {
- try {
- return parentClass.getMethod(methodName, parameterTypes);
- } catch (NoSuchMethodException e) {
- return null;
- }
- }
- parentClass = parentClass.getSuperclass();
- }
- return null;
- }
-
- /**
- * Returns an accessible method (that is, one that can be invoked via
- * reflection) that implements the specified method, by scanning through
- * all implemented interfaces and subinterfaces. If no such method
- * can be found, return null.
- *
- * There isn't any good reason why this method must be private.
- * It is because there doesn't seem any reason why other classes should
- * call this rather than the higher level methods.
- *
- * @param cls Parent class for the interfaces to be checked
- * @param methodName Method name of the method we wish to call
- * @param parameterTypes The parameter type signatures
- * @return the accessible method or null if not found
- */
- private static Method getAccessibleMethodFromInterfaceNest(Class> cls,
- String methodName, Class>... parameterTypes) {
- Method method = null;
-
- // Search up the superclass chain
- for (; cls != null; cls = cls.getSuperclass()) {
-
- // Check the implemented interfaces of the parent class
- Class>[] interfaces = cls.getInterfaces();
- for (int i = 0; i < interfaces.length; i++) {
- // Is this interface public?
- if (!Modifier.isPublic(interfaces[i].getModifiers())) {
- continue;
- }
- // Does the method exist on this interface?
- try {
- method = interfaces[i].getDeclaredMethod(methodName,
- parameterTypes);
- } catch (NoSuchMethodException e) { // NOPMD
- /*
- * Swallow, if no method is found after the loop then this
- * method returns null.
- */
- }
- if (method != null) {
- break;
- }
- // Recursively check our parent interfaces
- method = getAccessibleMethodFromInterfaceNest(interfaces[i],
- methodName, parameterTypes);
- if (method != null) {
- break;
- }
- }
- }
- return method;
- }
-
- /**
- * Finds an accessible method that matches the given name and has compatible parameters.
- * Compatible parameters mean that every method parameter is assignable from
- * the given parameters.
- * In other words, it finds a method with the given name
- * that will take the parameters given.
- *
- *
This method is used by
- * {@link
- * #invokeMethod(Object object, String methodName, Object[] args, Class[] parameterTypes)}.
- *
- *
This method can match primitive parameter by passing in wrapper classes.
- * For example, a Boolean will match a primitive boolean
- * parameter.
- *
- * @param cls find method in this class
- * @param methodName find method with this name
- * @param parameterTypes find method with most compatible parameters
- * @return The accessible method
- */
- public static Method getMatchingAccessibleMethod(Class> cls,
- String methodName, Class>... parameterTypes) {
- try {
- Method method = cls.getMethod(methodName, parameterTypes);
- MemberUtils.setAccessibleWorkaround(method);
- return method;
- } catch (NoSuchMethodException e) { // NOPMD - Swallow the exception
- }
- // search through all methods
- Method bestMatch = null;
- Method[] methods = cls.getMethods();
- for (Method method : methods) {
- // compare name and parameters
- if (method.getName().equals(methodName) && ClassUtils.isAssignable(parameterTypes, method.getParameterTypes(), true)) {
- // get accessible version of method
- Method accessibleMethod = getAccessibleMethod(method);
- if (accessibleMethod != null && (bestMatch == null || MemberUtils.compareParameterTypes(
- accessibleMethod.getParameterTypes(),
- bestMatch.getParameterTypes(),
- parameterTypes) < 0)) {
- bestMatch = accessibleMethod;
- }
- }
- }
- if (bestMatch != null) {
- MemberUtils.setAccessibleWorkaround(bestMatch);
- }
- return bestMatch;
- }
-}
diff --git a/core/src/main/java/external/org/apache/commons/lang3/reflect/package.html b/core/src/main/java/external/org/apache/commons/lang3/reflect/package.html
deleted file mode 100644
index 618b07a8..00000000
--- a/core/src/main/java/external/org/apache/commons/lang3/reflect/package.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-Accumulates common high-level uses of the java.lang.reflect APIs.
-@since 3.0
-These classes are immutable, and therefore thread-safe.
-
-
diff --git a/core/src/main/java/external/org/apache/commons/lang3/tuple/ImmutablePair.java b/core/src/main/java/external/org/apache/commons/lang3/tuple/ImmutablePair.java
deleted file mode 100644
index d3085be1..00000000
--- a/core/src/main/java/external/org/apache/commons/lang3/tuple/ImmutablePair.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package external.org.apache.commons.lang3.tuple;
-
-/**
- * An immutable pair consisting of two {@code Object} elements.
- *
- * Although the implementation is immutable, there is no restriction on the objects
- * that may be stored. If mutable objects are stored in the pair, then the pair
- * itself effectively becomes mutable. The class is also not {@code final}, so a subclass
- * could add undesirable behaviour.
- *
- * #ThreadSafe# if the objects are threadsafe
- *
- * @param the left element type
- * @param the right element type
- *
- * @since Lang 3.0
- * @version $Id: ImmutablePair.java 1127544 2011-05-25 14:35:42Z scolebourne $
- */
-public final class ImmutablePair extends Pair {
-
- /** Serialization version */
- private static final long serialVersionUID = 4954918890077093841L;
-
- /** Left object */
- public final L left;
- /** Right object */
- public final R right;
-
- /**
- * Obtains an immutable pair of from two objects inferring the generic types.
- *
- * This factory allows the pair to be created using inference to
- * obtain the generic types.
- *
- * @param the left element type
- * @param the right element type
- * @param left the left element, may be null
- * @param right the right element, may be null
- * @return a pair formed from the two parameters, not null
- */
- public static ImmutablePair of(L left, R right) {
- return new ImmutablePair(left, right);
- }
-
- /**
- * Create a new pair instance.
- *
- * @param left the left value, may be null
- * @param right the right value, may be null
- */
- public ImmutablePair(L left, R right) {
- super();
- this.left = left;
- this.right = right;
- }
-
- //-----------------------------------------------------------------------
- /**
- * {@inheritDoc}
- */
- @Override
- public L getLeft() {
- return left;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public R getRight() {
- return right;
- }
-
- /**
- * Throws {@code UnsupportedOperationException}.
- *
- * This pair is immutable, so this operation is not supported.
- *
- * @param value the value to set
- * @return never
- * @throws UnsupportedOperationException as this operation is not supported
- */
- public R setValue(R value) {
- throw new UnsupportedOperationException();
- }
-
-}
diff --git a/core/src/main/java/external/org/apache/commons/lang3/tuple/Pair.java b/core/src/main/java/external/org/apache/commons/lang3/tuple/Pair.java
deleted file mode 100644
index e43bd8ab..00000000
--- a/core/src/main/java/external/org/apache/commons/lang3/tuple/Pair.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package external.org.apache.commons.lang3.tuple;
-
-import java.io.Serializable;
-import java.util.Map;
-
-
-import external.org.apache.commons.lang3.ObjectUtils;
-import external.org.apache.commons.lang3.builder.CompareToBuilder;
-
-/**
- * A pair consisting of two elements.
- *
- * This class is an abstract implementation defining the basic API.
- * It refers to the elements as 'left' and 'right'. It also implements the
- * {@code Map.Entry} interface where the key is 'left' and the value is 'right'.
- *
- * Subclass implementations may be mutable or immutable.
- * However, there is no restriction on the type of the stored objects that may be stored.
- * If mutable objects are stored in the pair, then the pair itself effectively becomes mutable.
- *
- * @param the left element type
- * @param the right element type
- *
- * @since Lang 3.0
- * @version $Id: Pair.java 1142401 2011-07-03 08:30:12Z bayard $
- */
-public abstract class Pair implements Map.Entry, Comparable>, Serializable {
-
- /** Serialization version */
- private static final long serialVersionUID = 4954918890077093841L;
-
- /**
- * Obtains an immutable pair of from two objects inferring the generic types.
- *
- * This factory allows the pair to be created using inference to
- * obtain the generic types.
- *
- * @param the left element type
- * @param the right element type
- * @param left the left element, may be null
- * @param right the right element, may be null
- * @return a pair formed from the two parameters, not null
- */
- public static Pair of(L left, R right) {
- return new ImmutablePair(left, right);
- }
-
- //-----------------------------------------------------------------------
- /**
- * Gets the left element from this pair.
- *
- * When treated as a key-value pair, this is the key.
- *
- * @return the left element, may be null
- */
- public abstract L getLeft();
-
- /**
- * Gets the right element from this pair.
- *
- * When treated as a key-value pair, this is the value.
- *
- * @return the right element, may be null
- */
- public abstract R getRight();
-
- /**
- * Gets the key from this pair.
- *
- * This method implements the {@code Map.Entry} interface returning the
- * left element as the key.
- *
- * @return the left element as the key, may be null
- */
- public final L getKey() {
- return getLeft();
- }
-
- /**
- * Gets the value from this pair.
- *
- * This method implements the {@code Map.Entry} interface returning the
- * right element as the value.
- *
- * @return the right element as the value, may be null
- */
- public R getValue() {
- return getRight();
- }
-
- //-----------------------------------------------------------------------
- /**
- * Compares the pair based on the left element followed by the right element.
- * The types must be {@code Comparable}.
- *
- * @param other the other pair, not null
- * @return negative if this is less, zero if equal, positive if greater
- */
- public int compareTo(Pair other) {
- return new CompareToBuilder().append(getLeft(), other.getLeft())
- .append(getRight(), other.getRight()).toComparison();
- }
-
- /**
- * Compares this pair to another based on the two elements.
- *
- * @param obj the object to compare to, null returns false
- * @return true if the elements of the pair are equal
- */
- @Override
- public boolean equals(Object obj) {
- if (obj == this) {
- return true;
- }
- if (obj instanceof Map.Entry, ?>) {
- Map.Entry, ?> other = (Map.Entry, ?>) obj;
- return ObjectUtils.equals(getKey(), other.getKey())
- && ObjectUtils.equals(getValue(), other.getValue());
- }
- return false;
- }
-
- /**
- * Returns a suitable hash code.
- * The hash code follows the definition in {@code Map.Entry}.
- *
- * @return the hash code
- */
- @Override
- public int hashCode() {
- // see Map.Entry API specification
- return (getKey() == null ? 0 : getKey().hashCode()) ^
- (getValue() == null ? 0 : getValue().hashCode());
- }
-
- /**
- * Returns a String representation of this pair using the format {@code ($left,$right)}.
- *
- * @return a string describing this object, not null
- */
- @Override
- public String toString() {
- return new StringBuilder().append('(').append(getLeft()).append(',').append(getRight()).append(')').toString();
- }
-
- /**
- * Formats the receiver using the given format.
- *
- * This uses {@link java.util.Formattable} to perform the formatting. Two variables may
- * be used to embed the left and right elements. Use {@code %1$s} for the left
- * element (key) and {@code %2$s} for the right element (value).
- * The default format used by {@code toString()} is {@code (%1$s,%2$s)}.
- *
- * @param format the format string, optionally containing {@code %1$s} and {@code %2$s}, not null
- * @return the formatted string, not null
- */
- public String toString(String format) {
- return String.format(format, getLeft(), getRight());
- }
-
-}
diff --git a/core/src/main/java/external/org/apache/commons/lang3/tuple/package.html b/core/src/main/java/external/org/apache/commons/lang3/tuple/package.html
deleted file mode 100644
index db858539..00000000
--- a/core/src/main/java/external/org/apache/commons/lang3/tuple/package.html
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-Tuple classes, starting with a Pair class in version 3.0.
-@since 3.0
-
-
diff --git a/core/src/main/java/org/apache/commons/lang3/reflect/MemberUtilsX.java b/core/src/main/java/org/apache/commons/lang3/reflect/MemberUtilsX.java
new file mode 100644
index 00000000..36c87209
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/lang3/reflect/MemberUtilsX.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.lang3.reflect;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+
+public class MemberUtilsX {
+ public static int compareConstructorFit(final Constructor> left, final Constructor> right, final Class>[] actual) {
+ return MemberUtils.compareConstructorFit(left, right, actual);
+ }
+
+ public static int compareMethodFit(final Method left, final Method right, final Class>[] actual) {
+ return MemberUtils.compareMethodFit(left, right, actual);
+ }
+}
diff --git a/core/src/main/java/pxb/android/ResConst.java b/core/src/main/java/pxb/android/ResConst.java
deleted file mode 100644
index be0d87a8..00000000
--- a/core/src/main/java/pxb/android/ResConst.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2009-2013 Panxiaobo
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package pxb.android;
-
-public interface ResConst {
- int RES_STRING_POOL_TYPE = 0x0001;
- int RES_TABLE_TYPE = 0x0002;
- int RES_TABLE_PACKAGE_TYPE = 0x0200;
- int RES_TABLE_TYPE_SPEC_TYPE = 0x0202;
- int RES_TABLE_TYPE_TYPE = 0x0201;
-
- int RES_XML_TYPE = 0x0003;
- int RES_XML_RESOURCE_MAP_TYPE = 0x0180;
- int RES_XML_END_NAMESPACE_TYPE = 0x0101;
- int RES_XML_END_ELEMENT_TYPE = 0x0103;
- int RES_XML_START_NAMESPACE_TYPE = 0x0100;
- int RES_XML_START_ELEMENT_TYPE = 0x0102;
- int RES_XML_CDATA_TYPE = 0x0104;
-
-}
diff --git a/core/src/main/java/pxb/android/StringItem.java b/core/src/main/java/pxb/android/StringItem.java
deleted file mode 100644
index 7f99ecba..00000000
--- a/core/src/main/java/pxb/android/StringItem.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 2009-2013 Panxiaobo
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package pxb.android;
-
-public class StringItem {
- public String data;
- public int dataOffset;
- public int index;
-
- public StringItem() {
- super();
- }
-
- public StringItem(String data) {
- super();
- this.data = data;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- StringItem other = (StringItem) obj;
- if (data == null) {
- if (other.data != null)
- return false;
- } else if (!data.equals(other.data))
- return false;
- return true;
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((data == null) ? 0 : data.hashCode());
- return result;
- }
-
- public String toString() {
- return String.format("S%04d %s", index, data);
- }
-
-}
diff --git a/core/src/main/java/pxb/android/StringItems.java b/core/src/main/java/pxb/android/StringItems.java
deleted file mode 100644
index edf026a6..00000000
--- a/core/src/main/java/pxb/android/StringItems.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright (c) 2009-2013 Panxiaobo
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package pxb.android;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Map;
-
-@SuppressWarnings("serial")
-public class StringItems extends ArrayList {
- private static final int UTF8_FLAG = 0x00000100;
-
-
- public static String[] read(ByteBuffer in) throws IOException {
- int trunkOffset = in.position() - 8;
- int stringCount = in.getInt();
- int styleOffsetCount = in.getInt();
- int flags = in.getInt();
- int stringDataOffset = in.getInt();
- int stylesOffset = in.getInt();
- int offsets[] = new int[stringCount];
- String strings[] = new String[stringCount];
- for (int i = 0; i < stringCount; i++) {
- offsets[i] = in.getInt();
- }
-
- int base = trunkOffset + stringDataOffset;
- for (int i = 0; i < offsets.length; i++) {
- in.position(base + offsets[i]);
- String s;
-
- if (0 != (flags & UTF8_FLAG)) {
- u8length(in); // ignored
- int u8len = u8length(in);
- int start = in.position();
- int blength = u8len;
- while (in.get(start + blength) != 0) {
- blength++;
- }
- s = new String(in.array(), start, blength, "UTF-8");
- } else {
- int length = u16length(in);
- s = new String(in.array(), in.position(), length * 2, "UTF-16LE");
- }
- strings[i] = s;
- }
- return strings;
- }
-
- static int u16length(ByteBuffer in) {
- int length = in.getShort() & 0xFFFF;
- if (length > 0x7FFF) {
- length = ((length & 0x7FFF) << 8) | (in.getShort() & 0xFFFF);
- }
- return length;
- }
-
- static int u8length(ByteBuffer in) {
- int len = in.get() & 0xFF;
- if ((len & 0x80) != 0) {
- len = ((len & 0x7F) << 8) | (in.get() & 0xFF);
- }
- return len;
- }
-
- byte[] stringData;
-
- public int getSize() {
- return 5 * 4 + this.size() * 4 + stringData.length + 0;// TODO
- }
-
- public void prepare() throws IOException {
- for (StringItem s : this) {
- if (s.data.length() > 0x7FFF) {
- useUTF8 = false;
- }
- }
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- int i = 0;
- int offset = 0;
- baos.reset();
- Map map = new HashMap();
- for (StringItem item : this) {
- item.index = i++;
- String stringData = item.data;
- Integer of = map.get(stringData);
- if (of != null) {
- item.dataOffset = of;
- } else {
- item.dataOffset = offset;
- map.put(stringData, offset);
- if (useUTF8) {
- int length = stringData.length();
- byte[] data = stringData.getBytes("UTF-8");
- int u8lenght = data.length;
-
- if (length > 0x7F) {
- offset++;
- baos.write((length >> 8) | 0x80);
- }
- baos.write(length);
-
- if (u8lenght > 0x7F) {
- offset++;
- baos.write((u8lenght >> 8) | 0x80);
- }
- baos.write(u8lenght);
- baos.write(data);
- baos.write(0);
- offset += 3 + u8lenght;
- } else {
- int length = stringData.length();
- byte[] data = stringData.getBytes("UTF-16LE");
- if (length > 0x7FFF) {
- int x = (length >> 16) | 0x8000;
- baos.write(x);
- baos.write(x >> 8);
- offset += 2;
- }
- baos.write(length);
- baos.write(length >> 8);
- baos.write(data);
- baos.write(0);
- baos.write(0);
- offset += 4 + data.length;
- }
- }
- }
- // TODO
- stringData = baos.toByteArray();
- }
-
- private boolean useUTF8 = true;
-
- public void write(ByteBuffer out) throws IOException {
- out.putInt(this.size());
- out.putInt(0);// TODO style count
- out.putInt(useUTF8 ? UTF8_FLAG : 0);
- out.putInt(7 * 4 + this.size() * 4);
- out.putInt(0);
- for (StringItem item : this) {
- out.putInt(item.dataOffset);
- }
- out.put(stringData);
- // TODO
- }
-}
diff --git a/core/src/main/java/pxb/android/arsc/ArscDumper.java b/core/src/main/java/pxb/android/arsc/ArscDumper.java
deleted file mode 100644
index 1e5760d2..00000000
--- a/core/src/main/java/pxb/android/arsc/ArscDumper.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 2009-2013 Panxiaobo
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package pxb.android.arsc;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-import pxb.android.axml.Util;
-
-/**
- * dump an arsc file
- *
- * @author bob
- *
- */
-public class ArscDumper {
- public static void dump(List pkgs) {
- for (int x = 0; x < pkgs.size(); x++) {
- Pkg pkg = pkgs.get(x);
-
- System.out.println(String.format(" Package %d id=%d name=%s typeCount=%d", x, pkg.id, pkg.name,
- pkg.types.size()));
- for (Type type : pkg.types.values()) {
- System.out.println(String.format(" type %d %s", type.id - 1, type.name));
-
- int resPrefix = pkg.id << 24 | type.id << 16;
- for (int i = 0; i < type.specs.length; i++) {
- ResSpec spec = type.getSpec(i);
- System.out.println(String.format(" spec 0x%08x 0x%08x %s", resPrefix | spec.id, spec.flags,
- spec.name));
- }
- for (int i = 0; i < type.configs.size(); i++) {
- Config config = type.configs.get(i);
- System.out.println(" config");
-
- List entries = new ArrayList(config.resources.values());
- for (int j = 0; j < entries.size(); j++) {
- ResEntry entry = entries.get(j);
- System.out.println(String.format(" resource 0x%08x %-20s: %s",
- resPrefix | entry.spec.id, entry.spec.name, entry.value));
- }
- }
- }
- }
- }
-
- public static void main(String... args) throws IOException {
- if (args.length == 0) {
- System.err.println("asrc-dump file.arsc");
- return;
- }
- byte[] data = Util.readFile(new File(args[0]));
- List pkgs = new ArscParser(data).parse();
-
- dump(pkgs);
-
- }
-}
diff --git a/core/src/main/java/pxb/android/arsc/ArscParser.java b/core/src/main/java/pxb/android/arsc/ArscParser.java
deleted file mode 100644
index 721c1406..00000000
--- a/core/src/main/java/pxb/android/arsc/ArscParser.java
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- * Copyright (c) 2009-2013 Panxiaobo
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package pxb.android.arsc;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.AbstractMap;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import pxb.android.ResConst;
-import pxb.android.StringItems;
-
-/**
- *
- * Read the resources.arsc inside an Android apk.
- *
- * Usage:
- *
- *
- * byte[] oldArscFile= ... ; //
- * List<Pkg> pkgs = new ArscParser(oldArscFile).parse(); // read the file
- * modify(pkgs); // do what you want here
- * byte[] newArscFile = new ArscWriter(pkgs).toByteArray(); // build a new file
- *
- *
- * The format of arsc is described here (gingerbread)
- *
- * frameworks/base/libs/utils/ResourceTypes.cpp
- * frameworks/base/include/utils/ResourceTypes.h
- *
- * and the cmd line aapt d resources abc.apk is also good for debug
- * (available in android sdk)
- *
- *
- * Todos:
- *
- * TODO add support to read styled strings
- *
- *
- *
- * Thanks to the the following projects
- *
- * android4me https://code.google.com/p/android4me/
- * Apktool https://code.google.com/p/android-apktool
- * Android http://source.android.com/
- *
- *
- * @author bob
- *
- */
-public class ArscParser implements ResConst {
-
- /* pkg */class Chunk {
-
- public final int headSize;
- public final int location;
- public final int size;
- public final int type;
-
- public Chunk() {
- location = in.position();
- type = in.getShort() & 0xFFFF;
- headSize = in.getShort() & 0xFFFF;
- size = in.getInt();
- }
- }
-
- /**
- * If set, this resource has been declared public, so libraries are allowed
- * to reference it.
- */
- static final int ENGRY_FLAG_PUBLIC = 0x0002;
-
- /**
- * If set, this is a complex entry, holding a set of name/value mappings. It
- * is followed by an array of ResTable_map structures.
- */
- final static short ENTRY_FLAG_COMPLEX = 0x0001;
- public static final int TYPE_STRING = 0x03;
-
- private int fileSize = -1;
- private ByteBuffer in;
- private String[] keyNamesX;
- private Pkg pkg;
- private List pkgs = new ArrayList();
- private String[] strings;
- private String[] typeNamesX;
-
- public ArscParser(byte[] b) {
- this.in = ByteBuffer.wrap(b).order(ByteOrder.LITTLE_ENDIAN);
- }
-
- public List parse() throws IOException {
- if (fileSize < 0) {
- Chunk head = new Chunk();
- if (head.type != RES_TABLE_TYPE) {
- throw new RuntimeException();
- }
- fileSize = head.size;
- in.getInt();// packagecount
- }
- while (in.hasRemaining()) {
- Chunk chunk = new Chunk();
- switch (chunk.type) {
- case RES_STRING_POOL_TYPE:
- strings = StringItems.read(in);
- break;
- case RES_TABLE_PACKAGE_TYPE:
- readPackage(in);
- }
- in.position(chunk.location + chunk.size);
- }
- return pkgs;
- }
-
- // private void readConfigFlags() {
- // int size = in.getInt();
- // if (size < 28) {
- // throw new RuntimeException();
- // }
- // short mcc = in.getShort();
- // short mnc = in.getShort();
- //
- // char[] language = new char[] { (char) in.get(), (char) in.get() };
- // char[] country = new char[] { (char) in.get(), (char) in.get() };
- //
- // byte orientation = in.get();
- // byte touchscreen = in.get();
- // short density = in.getShort();
- //
- // byte keyboard = in.get();
- // byte navigation = in.get();
- // byte inputFlags = in.get();
- // byte inputPad0 = in.get();
- //
- // short screenWidth = in.getShort();
- // short screenHeight = in.getShort();
- //
- // short sdkVersion = in.getShort();
- // short minorVersion = in.getShort();
- //
- // byte screenLayout = 0;
- // byte uiMode = 0;
- // short smallestScreenWidthDp = 0;
- // if (size >= 32) {
- // screenLayout = in.get();
- // uiMode = in.get();
- // smallestScreenWidthDp = in.getShort();
- // }
- //
- // short screenWidthDp = 0;
- // short screenHeightDp = 0;
- //
- // if (size >= 36) {
- // screenWidthDp = in.getShort();
- // screenHeightDp = in.getShort();
- // }
- //
- // short layoutDirection = 0;
- // if (size >= 38 && sdkVersion >= 17) {
- // layoutDirection = in.getShort();
- // }
- //
- // }
-
- private void readEntry(Config config, ResSpec spec) {
- int size = in.getShort();
-
- int flags = in.getShort(); // ENTRY_FLAG_PUBLIC
- int keyStr = in.getInt();
- spec.updateName(keyNamesX[keyStr]);
-
- ResEntry resEntry = new ResEntry(flags, spec);
-
- if (0 != (flags & ENTRY_FLAG_COMPLEX)) {
-
- int parent = in.getInt();
- int count = in.getInt();
- BagValue bag = new BagValue(parent);
- for (int i = 0; i < count; i++) {
- Map.Entry entry = new AbstractMap.SimpleEntry(in.getInt(), readValue());
- bag.map.add(entry);
- }
- resEntry.value = bag;
- } else {
- resEntry.value = readValue();
- }
- config.resources.put(spec.id, resEntry);
- }
-
- private void readPackage(ByteBuffer in) throws IOException {
- int pid = in.getInt() % 0xFF;
-
- String name;
- {
- int nextPisition = in.position() + 128 * 2;
- StringBuilder sb = new StringBuilder(32);
- for (int i = 0; i < 128; i++) {
- int s = in.getShort();
- if (s == 0) {
- break;
- } else {
- sb.append((char) s);
- }
- }
- name = sb.toString();
- in.position(nextPisition);
- }
-
- pkg = new Pkg(pid, name);
- pkgs.add(pkg);
-
- int typeStringOff = in.getInt();
- int typeNameCount = in.getInt();
- int keyStringOff = in.getInt();
- int specNameCount = in.getInt();
-
- {
- Chunk chunk = new Chunk();
- if (chunk.type != RES_STRING_POOL_TYPE) {
- throw new RuntimeException();
- }
- typeNamesX = StringItems.read(in);
- in.position(chunk.location + chunk.size);
- }
- {
- Chunk chunk = new Chunk();
- if (chunk.type != RES_STRING_POOL_TYPE) {
- throw new RuntimeException();
- }
- keyNamesX = StringItems.read(in);
- in.position(chunk.location + chunk.size);
- }
-
- out: while (in.hasRemaining()) {
- Chunk chunk = new Chunk();
- switch (chunk.type) {
- case RES_TABLE_TYPE_SPEC_TYPE: {
- int tid = in.get() & 0xFF;
- in.get(); // res0
- in.getShort();// res1
- int entryCount = in.getInt();
-
- Type t = pkg.getType(tid, typeNamesX[tid - 1], entryCount);
- for (int i = 0; i < entryCount; i++) {
- t.getSpec(i).flags = in.getInt();
- }
- }
- break;
- case RES_TABLE_TYPE_TYPE: {
- int tid = in.get() & 0xFF;
- in.get(); // res0
- in.getShort();// res1
- int entryCount = in.getInt();
- Type t = pkg.getType(tid, typeNamesX[tid - 1], entryCount);
- int entriesStart = in.getInt();
-
- int p = in.position();
- int size = in.getInt();
- // readConfigFlags();
- byte[] data = new byte[size];
- in.position(p);
- in.get(data);
- Config config = new Config(data, entryCount);
-
- in.position(chunk.location + chunk.headSize);
-
- int[] entrys = new int[entryCount];
- for (int i = 0; i < entryCount; i++) {
- entrys[i] = in.getInt();
- }
- for (int i = 0; i < entrys.length; i++) {
- if (entrys[i] != -1) {
- in.position(chunk.location + entriesStart + entrys[i]);
- ResSpec spec = t.getSpec(i);
- readEntry(config, spec);
- }
- }
-
- t.addConfig(config);
- }
- break;
- default:
- break out;
- }
- in.position(chunk.location + chunk.size);
- }
- }
-
- private Object readValue() {
- int size1 = in.getShort();// 8
- int zero = in.get();// 0
- int type = in.get() & 0xFF; // TypedValue.*
- int data = in.getInt();
- String raw = null;
- if (type == TYPE_STRING) {
- raw = strings[data];
- }
- return new Value(type, data, raw);
- }
-}
diff --git a/core/src/main/java/pxb/android/arsc/ArscWriter.java b/core/src/main/java/pxb/android/arsc/ArscWriter.java
deleted file mode 100644
index 082c42f9..00000000
--- a/core/src/main/java/pxb/android/arsc/ArscWriter.java
+++ /dev/null
@@ -1,400 +0,0 @@
-/*
- * Copyright (c) 2009-2013 Panxiaobo
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package pxb.android.arsc;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.TreeMap;
-
-import pxb.android.ResConst;
-import pxb.android.StringItem;
-import pxb.android.StringItems;
-import pxb.android.axml.Util;
-
-/**
- * Write pkgs to an arsc file
- *
- * @see ArscParser
- * @author bob
- *
- */
-public class ArscWriter implements ResConst {
- private static class PkgCtx {
- Map keyNames = new HashMap();
- StringItems keyNames0 = new StringItems();
- public int keyStringOff;
- int offset;
- Pkg pkg;
- int pkgSize;
- List typeNames = new ArrayList();
-
- StringItems typeNames0 = new StringItems();
- int typeStringOff;
-
- public void addKeyName(String name) {
- if (keyNames.containsKey(name)) {
- return;
- }
- StringItem stringItem = new StringItem(name);
- keyNames.put(name, stringItem);
- keyNames0.add(stringItem);
- }
-
- public void addTypeName(int id, String name) {
- while (typeNames.size() <= id) {
- typeNames.add(null);
- }
-
- StringItem item = typeNames.get(id);
- if (item == null) {
- typeNames.set(id, new StringItem(name));
- } else {
- throw new RuntimeException();
- }
- }
- }
-
- private static void D(String fmt, Object... args) {
-
- }
-
- private List ctxs = new ArrayList(5);
- private List pkgs;
- private Map strTable = new TreeMap();
- private StringItems strTable0 = new StringItems();
-
- public ArscWriter(List pkgs) {
- this.pkgs = pkgs;
- }
-
- public static void main(String... args) throws IOException {
- if (args.length < 2) {
- System.err.println("asrc-write-test in.arsc out.arsc");
- return;
- }
- byte[] data = Util.readFile(new File(args[0]));
- List pkgs = new ArscParser(data).parse();
- // ArscDumper.dump(pkgs);
- byte[] data2 = new ArscWriter(pkgs).toByteArray();
- // ArscDumper.dump(new ArscParser(data2).parse());
- Util.writeFile(data2, new File(args[1]));
- }
-
- private void addString(String str) {
- if (strTable.containsKey(str)) {
- return;
- }
- StringItem stringItem = new StringItem(str);
- strTable.put(str, stringItem);
- strTable0.add(stringItem);
- }
-
- private int count() {
-
- int size = 0;
-
- size += 8 + 4;// chunk, pkgcount
- {
- int stringSize = strTable0.getSize();
- if (stringSize % 4 != 0) {
- stringSize += 4 - stringSize % 4;
- }
- size += 8 + stringSize;// global strings
- }
- for (PkgCtx ctx : ctxs) {
- ctx.offset = size;
- int pkgSize = 0;
- pkgSize += 8 + 4 + 256;// chunk,pid+name
- pkgSize += 4 * 4;
-
- ctx.typeStringOff = pkgSize;
- {
- int stringSize = ctx.typeNames0.getSize();
- if (stringSize % 4 != 0) {
- stringSize += 4 - stringSize % 4;
- }
- pkgSize += 8 + stringSize;// type names
- }
-
- ctx.keyStringOff = pkgSize;
-
- {
- int stringSize = ctx.keyNames0.getSize();
- if (stringSize % 4 != 0) {
- stringSize += 4 - stringSize % 4;
- }
- pkgSize += 8 + stringSize;// key names
- }
-
- for (Type type : ctx.pkg.types.values()) {
- type.wPosition = size + pkgSize;
- pkgSize += 8 + 4 + 4 + 4 * type.specs.length; // trunk,id,entryCount,
- // configs
-
- for (Config config : type.configs) {
- config.wPosition = pkgSize + size;
- int configBasePostion = pkgSize;
- pkgSize += 8 + 4 + 4 + 4; // trunk,id,entryCount,entriesStart
- int size0 = config.id.length;
- if (size0 % 4 != 0) {
- size0 += 4 - size0 % 4;
- }
- pkgSize += size0;// config
-
- if (pkgSize - configBasePostion > 0x0038) {
- throw new RuntimeException("config id too big");
- } else {
- pkgSize = configBasePostion + 0x0038;
- }
-
- pkgSize += 4 * config.entryCount;// offset
- config.wEntryStart = pkgSize - configBasePostion;
- int entryBase = pkgSize;
- for (ResEntry e : config.resources.values()) {
- e.wOffset = pkgSize - entryBase;
- pkgSize += 8;// size,flag,keyString
- if (e.value instanceof BagValue) {
- BagValue big = (BagValue) e.value;
- pkgSize += 8 + big.map.size() * 12;
- } else {
- pkgSize += 8;
- }
- }
- config.wChunkSize = pkgSize - configBasePostion;
- }
- }
- ctx.pkgSize = pkgSize;
- size += pkgSize;
- }
-
- return size;
- }
-
- private List prepare() throws IOException {
- for (Pkg pkg : pkgs) {
- PkgCtx ctx = new PkgCtx();
- ctx.pkg = pkg;
- ctxs.add(ctx);
-
- for (Type type : pkg.types.values()) {
- ctx.addTypeName(type.id - 1, type.name);
- for (ResSpec spec : type.specs) {
- ctx.addKeyName(spec.name);
- }
- for (Config config : type.configs) {
- for (ResEntry e : config.resources.values()) {
- Object object = e.value;
- if (object instanceof BagValue) {
- travelBagValue((BagValue) object);
- } else {
- travelValue((Value) object);
- }
- }
- }
- }
- ctx.keyNames0.prepare();
- ctx.typeNames0.addAll(ctx.typeNames);
- ctx.typeNames0.prepare();
- }
- strTable0.prepare();
- return ctxs;
- }
-
- public byte[] toByteArray() throws IOException {
- prepare();
- int size = count();
- ByteBuffer out = ByteBuffer.allocate(size).order(ByteOrder.LITTLE_ENDIAN);
- write(out, size);
- return out.array();
- }
-
- private void travelBagValue(BagValue bag) {
- for (Map.Entry e : bag.map) {
- travelValue(e.getValue());
- }
- }
-
- private void travelValue(Value v) {
- if (v.raw != null) {
- addString(v.raw);
- }
- }
-
- private void write(ByteBuffer out, int size) throws IOException {
- out.putInt(RES_TABLE_TYPE | (0x000c << 16));
- out.putInt(size);
- out.putInt(ctxs.size());
-
- {
- int stringSize = strTable0.getSize();
- int padding = 0;
- if (stringSize % 4 != 0) {
- padding = 4 - stringSize % 4;
- }
- out.putInt(RES_STRING_POOL_TYPE | (0x001C << 16));
- out.putInt(stringSize + padding + 8);
- strTable0.write(out);
- out.put(new byte[padding]);
- }
-
- for (PkgCtx pctx : ctxs) {
- if (out.position() != pctx.offset) {
- throw new RuntimeException();
- }
- final int basePosition = out.position();
- out.putInt(RES_TABLE_PACKAGE_TYPE | (0x011c << 16));
- out.putInt(pctx.pkgSize);
- out.putInt(pctx.pkg.id);
- int p = out.position();
- out.put(pctx.pkg.name.getBytes("UTF-16LE"));
- out.position(p + 256);
-
- out.putInt(pctx.typeStringOff);
- out.putInt(pctx.typeNames0.size());
-
- out.putInt(pctx.keyStringOff);
- out.putInt(pctx.keyNames0.size());
-
- {
- if (out.position() - basePosition != pctx.typeStringOff) {
- throw new RuntimeException();
- }
- int stringSize = pctx.typeNames0.getSize();
- int padding = 0;
- if (stringSize % 4 != 0) {
- padding = 4 - stringSize % 4;
- }
- out.putInt(RES_STRING_POOL_TYPE | (0x001C << 16));
- out.putInt(stringSize + padding + 8);
- pctx.typeNames0.write(out);
- out.put(new byte[padding]);
- }
-
- {
- if (out.position() - basePosition != pctx.keyStringOff) {
- throw new RuntimeException();
- }
- int stringSize = pctx.keyNames0.getSize();
- int padding = 0;
- if (stringSize % 4 != 0) {
- padding = 4 - stringSize % 4;
- }
- out.putInt(RES_STRING_POOL_TYPE | (0x001C << 16));
- out.putInt(stringSize + padding + 8);
- pctx.keyNames0.write(out);
- out.put(new byte[padding]);
- }
-
- for (Type t : pctx.pkg.types.values()) {
- D("[%08x]write spec", out.position(), t.name);
- if (t.wPosition != out.position()) {
- throw new RuntimeException();
- }
- out.putInt(RES_TABLE_TYPE_SPEC_TYPE | (0x0010 << 16));
- out.putInt(4 * 4 + 4 * t.specs.length);// size
-
- out.putInt(t.id);
- out.putInt(t.specs.length);
- for (ResSpec spec : t.specs) {
- out.putInt(spec.flags);
- }
-
- for (Config config : t.configs) {
- D("[%08x]write config", out.position());
- int typeConfigPosition = out.position();
- if (config.wPosition != typeConfigPosition) {
- throw new RuntimeException();
- }
- out.putInt(RES_TABLE_TYPE_TYPE | (0x0038 << 16));
- out.putInt(config.wChunkSize);// size
-
- out.putInt(t.id);
- out.putInt(t.specs.length);
- out.putInt(config.wEntryStart);
-
- D("[%08x]write config ids", out.position());
- out.put(config.id);
-
- int size0 = config.id.length;
- int padding = 0;
- if (size0 % 4 != 0) {
- padding = 4 - size0 % 4;
- }
- out.put(new byte[padding]);
-
- out.position(typeConfigPosition + 0x0038);
-
- D("[%08x]write config entry offsets", out.position());
- for (int i = 0; i < config.entryCount; i++) {
- ResEntry entry = config.resources.get(i);
- if (entry == null) {
- out.putInt(-1);
- } else {
- out.putInt(entry.wOffset);
- }
- }
-
- if (out.position() - typeConfigPosition != config.wEntryStart) {
- throw new RuntimeException();
- }
- D("[%08x]write config entrys", out.position());
- for (ResEntry e : config.resources.values()) {
- D("[%08x]ResTable_entry", out.position());
- boolean isBag = e.value instanceof BagValue;
- out.putShort((short) (isBag ? 16 : 8));
- int flag = e.flag;
- if (isBag) { // add complex flag
- flag |= ArscParser.ENTRY_FLAG_COMPLEX;
- } else { // remove
- flag &= ~ArscParser.ENTRY_FLAG_COMPLEX;
- }
- out.putShort((short) flag);
- out.putInt(pctx.keyNames.get(e.spec.name).index);
- if (isBag) {
- BagValue bag = (BagValue) e.value;
- out.putInt(bag.parent);
- out.putInt(bag.map.size());
- for (Map.Entry entry : bag.map) {
- out.putInt(entry.getKey());
- writeValue(entry.getValue(), out);
- }
- } else {
- writeValue((Value) e.value, out);
- }
- }
- }
- }
- }
- }
-
- private void writeValue(Value value, ByteBuffer out) {
- out.putShort((short) 8);
- out.put((byte) 0);
- out.put((byte) value.type);
- if (value.type == ArscParser.TYPE_STRING) {
- out.putInt(strTable.get(value.raw).index);
- } else {
- out.putInt(value.data);
- }
- }
-
-}
diff --git a/core/src/main/java/pxb/android/arsc/BagValue.java b/core/src/main/java/pxb/android/arsc/BagValue.java
deleted file mode 100644
index f75ddd08..00000000
--- a/core/src/main/java/pxb/android/arsc/BagValue.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 2009-2013 Panxiaobo
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package pxb.android.arsc;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-public class BagValue {
- public List> map = new ArrayList>();
- public final int parent;
-
- public BagValue(int parent) {
- this.parent = parent;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (!(obj instanceof BagValue))
- return false;
- BagValue other = (BagValue) obj;
- if (map == null) {
- if (other.map != null)
- return false;
- } else if (!map.equals(other.map))
- return false;
- if (parent != other.parent)
- return false;
- return true;
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((map == null) ? 0 : map.hashCode());
- result = prime * result + parent;
- return result;
- }
-
- public String toString() {
- StringBuilder sb = new StringBuilder();
- sb.append(String.format("{bag%08x", parent));
- for (Map.Entry e : map) {
- sb.append(",").append(String.format("0x%08x", e.getKey()));
- sb.append("=");
- sb.append(e.getValue());
- }
-
- return sb.append("}").toString();
- }
-}
diff --git a/core/src/main/java/pxb/android/arsc/Config.java b/core/src/main/java/pxb/android/arsc/Config.java
deleted file mode 100644
index 66ec1048..00000000
--- a/core/src/main/java/pxb/android/arsc/Config.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2009-2013 Panxiaobo
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package pxb.android.arsc;
-
-import java.util.Map;
-import java.util.TreeMap;
-
-public class Config {
- public final int entryCount;
- public final byte[] id;
- public Map resources = new TreeMap();
- /* package */int wChunkSize;
- /* package */int wEntryStart;
- /* package */int wPosition;
-
- public Config(byte[] id, int entryCount) {
- super();
- this.id = id;
- this.entryCount = entryCount;
- }
-}
\ No newline at end of file
diff --git a/core/src/main/java/pxb/android/arsc/Pkg.java b/core/src/main/java/pxb/android/arsc/Pkg.java
deleted file mode 100644
index 909003cb..00000000
--- a/core/src/main/java/pxb/android/arsc/Pkg.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2009-2013 Panxiaobo
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package pxb.android.arsc;
-
-import java.util.TreeMap;
-
-public class Pkg {
- public final int id;
- public String name;
- public TreeMap types = new TreeMap();
-
- public Pkg(int id, String name) {
- super();
- this.id = id;
- this.name = name;
- }
-
- public Type getType(int tid, String name, int entrySize) {
- Type type = types.get(tid);
- if (type != null) {
- if (name != null) {
- if (type.name == null) {
- type.name = name;
- } else if (!name.endsWith(type.name)) {
- throw new RuntimeException();
- }
- if (type.specs.length != entrySize) {
- throw new RuntimeException();
- }
- }
- } else {
- type = new Type();
- type.id = tid;
- type.name = name;
- type.specs = new ResSpec[entrySize];
- types.put(tid, type);
- }
- return type;
- }
-
-}
\ No newline at end of file
diff --git a/core/src/main/java/pxb/android/arsc/ResEntry.java b/core/src/main/java/pxb/android/arsc/ResEntry.java
deleted file mode 100644
index bb45007e..00000000
--- a/core/src/main/java/pxb/android/arsc/ResEntry.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2009-2013 Panxiaobo
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package pxb.android.arsc;
-
-public class ResEntry {
- public final int flag;
-
- public final ResSpec spec;
- /**
- * {@link BagValue} or {@link Value}
- */
- public Object value;
-
- /* package */int wOffset;
-
- public ResEntry(int flag, ResSpec spec) {
- super();
- this.flag = flag;
- this.spec = spec;
- }
-
-}
\ No newline at end of file
diff --git a/core/src/main/java/pxb/android/arsc/ResSpec.java b/core/src/main/java/pxb/android/arsc/ResSpec.java
deleted file mode 100644
index 92193a2b..00000000
--- a/core/src/main/java/pxb/android/arsc/ResSpec.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2009-2013 Panxiaobo
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package pxb.android.arsc;
-
-public class ResSpec {
- public int flags;
- public final int id;
- public String name;
-
- public ResSpec(int id) {
- super();
- this.id = id;
- }
-
- public void updateName(String s) {
- String name = this.name;
- if (name == null) {
- this.name = s;
- } else if (!s.equals(name)) {
- throw new RuntimeException();
- }
- }
-}
\ No newline at end of file
diff --git a/core/src/main/java/pxb/android/arsc/Type.java b/core/src/main/java/pxb/android/arsc/Type.java
deleted file mode 100644
index 5f35d3d3..00000000
--- a/core/src/main/java/pxb/android/arsc/Type.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2009-2013 Panxiaobo
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package pxb.android.arsc;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class Type {
- public List configs = new ArrayList();
- public int id;
- public String name;
- public ResSpec[] specs;
- /* package */int wPosition;
-
- public void addConfig(Config config) {
- if (config.entryCount != specs.length) {
- throw new RuntimeException();
- }
- configs.add(config);
- }
-
- public ResSpec getSpec(int resId) {
- ResSpec res = specs[resId];
- if (res == null) {
- res = new ResSpec(resId);
- specs[resId] = res;
- }
- return res;
- }
-
-}
\ No newline at end of file
diff --git a/core/src/main/java/pxb/android/arsc/Value.java b/core/src/main/java/pxb/android/arsc/Value.java
deleted file mode 100644
index 56f90dba..00000000
--- a/core/src/main/java/pxb/android/arsc/Value.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2009-2013 Panxiaobo
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package pxb.android.arsc;
-
-public class Value {
- public final int data;
- public String raw;
- public final int type;
-
- public Value(int type, int data, String raw) {
- super();
- this.type = type;
- this.data = data;
- this.raw = raw;
- }
-
- public String toString() {
- if (type == 0x03) {
- return raw;
- }
- return String.format("{t=0x%02x d=0x%08x}", type, data);
- }
-
-}
diff --git a/core/src/main/java/pxb/android/axml/Axml.java b/core/src/main/java/pxb/android/axml/Axml.java
deleted file mode 100644
index 49879f7a..00000000
--- a/core/src/main/java/pxb/android/axml/Axml.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (c) 2009-2013 Panxiaobo
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package pxb.android.axml;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class Axml extends AxmlVisitor {
-
- public static class Node extends NodeVisitor {
- public static class Attr {
- public String ns, name;
- public int resourceId, type;
- public Object value;
-
- public void accept(NodeVisitor nodeVisitor) {
- nodeVisitor.attr(ns, name, resourceId, type, value);
- }
- }
-
- public static class Text {
- public int ln;
- public String text;
-
- public void accept(NodeVisitor nodeVisitor) {
- nodeVisitor.text(ln, text);
- }
- }
-
- public List attrs = new ArrayList();
- public List children = new ArrayList();
- public Integer ln;
- public String ns, name;
- public Text text;
-
- public void accept(NodeVisitor nodeVisitor) {
- NodeVisitor nodeVisitor2 = nodeVisitor.child(ns, name);
- acceptB(nodeVisitor2);
- nodeVisitor2.end();
- }
-
- public void acceptB(NodeVisitor nodeVisitor) {
- if (text != null) {
- text.accept(nodeVisitor);
- }
- for (Attr a : attrs) {
- a.accept(nodeVisitor);
- }
- if (ln != null) {
- nodeVisitor.line(ln);
- }
- for (Node c : children) {
- c.accept(nodeVisitor);
- }
- }
-
- @Override
- public void attr(String ns, String name, int resourceId, int type, Object obj) {
- Attr attr = new Attr();
- attr.name = name;
- attr.ns = ns;
- attr.resourceId = resourceId;
- attr.type = type;
- attr.value = obj;
- attrs.add(attr);
- }
-
- @Override
- public NodeVisitor child(String ns, String name) {
- Node node = new Node();
- node.name = name;
- node.ns = ns;
- children.add(node);
- return node;
- }
-
- @Override
- public void line(int ln) {
- this.ln = ln;
- }
-
- @Override
- public void text(int lineNumber, String value) {
- Text text = new Text();
- text.ln = lineNumber;
- text.text = value;
- this.text = text;
- }
- }
-
- public static class Ns {
- public int ln;
- public String prefix, uri;
-
- public void accept(AxmlVisitor visitor) {
- visitor.ns(prefix, uri, ln);
- }
- }
-
- public List firsts = new ArrayList();
- public List nses = new ArrayList();
-
- public void accept(final AxmlVisitor visitor) {
- for (Ns ns : nses) {
- ns.accept(visitor);
- }
- for (Node first : firsts) {
- first.accept(visitor);
- }
- }
-
- @Override
- public NodeVisitor child(String ns, String name) {
- Node node = new Node();
- node.name = name;
- node.ns = ns;
- firsts.add(node);
- return node;
- }
-
- @Override
- public void ns(String prefix, String uri, int ln) {
- Ns ns = new Ns();
- ns.prefix = prefix;
- ns.uri = uri;
- ns.ln = ln;
- nses.add(ns);
- }
-}
diff --git a/core/src/main/java/pxb/android/axml/AxmlParser.java b/core/src/main/java/pxb/android/axml/AxmlParser.java
deleted file mode 100644
index d3802451..00000000
--- a/core/src/main/java/pxb/android/axml/AxmlParser.java
+++ /dev/null
@@ -1,274 +0,0 @@
-/*
- * Copyright (c) 2009-2013 Panxiaobo
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package pxb.android.axml;
-
-import static pxb.android.axml.NodeVisitor.TYPE_INT_BOOLEAN;
-import static pxb.android.axml.NodeVisitor.TYPE_STRING;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.IntBuffer;
-
-import pxb.android.ResConst;
-import pxb.android.StringItems;
-
-/**
- * a class to read android axml
- *
- * @author Panxiaobo
- */
-public class AxmlParser implements ResConst {
-
- public static final int END_FILE = 7;
- public static final int END_NS = 5;
- public static final int END_TAG = 3;
- public static final int START_FILE = 1;
- public static final int START_NS = 4;
- public static final int START_TAG = 2;
- public static final int TEXT = 6;
- // private int attrName[];
- // private int attrNs[];
- // private int attrResId[];
- // private int attrType[];
- // private Object attrValue[];
-
- private int attributeCount;
-
- private IntBuffer attrs;
-
- private int classAttribute;
- private int fileSize = -1;
- private int idAttribute;
- private ByteBuffer in;
- private int lineNumber;
- private int nameIdx;
- private int nsIdx;
-
- private int prefixIdx;
-
- private int[] resourceIds;
-
- private String[] strings;
-
- private int styleAttribute;
-
- private int textIdx;
-
- public AxmlParser(byte[] data) {
- this(ByteBuffer.wrap(data));
- }
-
- public AxmlParser(ByteBuffer in) {
- super();
- this.in = in.order(ByteOrder.LITTLE_ENDIAN);
- }
-
- public int getAttrCount() {
- return attributeCount;
- }
-
- public int getAttributeCount() {
- return attributeCount;
- }
-
- public String getAttrName(int i) {
- int idx = attrs.get(i * 5 + 1);
- return strings[idx];
-
- }
-
- public String getAttrNs(int i) {
- int idx = attrs.get(i * 5 + 0);
- return idx >= 0 ? strings[idx] : null;
- }
-
- String getAttrRawString(int i) {
- int idx = attrs.get(i * 5 + 2);
- if (idx >= 0) {
- return strings[idx];
- }
- return null;
- }
-
- public int getAttrResId(int i) {
- if (resourceIds != null) {
- int idx = attrs.get(i * 5 + 1);
- if (idx >= 0 && idx < resourceIds.length) {
- return resourceIds[idx];
- }
- }
- return -1;
- }
-
- public int getAttrType(int i) {
- return attrs.get(i * 5 + 3) >> 24;
- }
-
- public Object getAttrValue(int i) {
- int v = attrs.get(i * 5 + 4);
-
- if (i == idAttribute) {
- return ValueWrapper.wrapId(v, getAttrRawString(i));
- } else if (i == styleAttribute) {
- return ValueWrapper.wrapStyle(v, getAttrRawString(i));
- } else if (i == classAttribute) {
- return ValueWrapper.wrapClass(v, getAttrRawString(i));
- }
-
- switch (getAttrType(i)) {
- case TYPE_STRING:
- return strings[v];
- case TYPE_INT_BOOLEAN:
- return v != 0;
- default:
- return v;
- }
- }
-
- public int getLineNumber() {
- return lineNumber;
- }
-
- public String getName() {
- return strings[nameIdx];
- }
-
- public String getNamespacePrefix() {
- return strings[prefixIdx];
- }
-
- public String getNamespaceUri() {
- return nsIdx >= 0 ? strings[nsIdx] : null;
- }
-
- public String getText() {
- return strings[textIdx];
- }
-
- public int next() throws IOException {
- if (fileSize < 0) {
- int type = in.getInt() & 0xFFFF;
- if (type != RES_XML_TYPE) {
- throw new RuntimeException();
- }
- fileSize = in.getInt();
- return START_FILE;
- }
- int event = -1;
- for (int p = in.position(); p < fileSize; p = in.position()) {
- int type = in.getInt() & 0xFFFF;
- int size = in.getInt();
- switch (type) {
- case RES_XML_START_ELEMENT_TYPE: {
- {
- lineNumber = in.getInt();
- in.getInt();/* skip, 0xFFFFFFFF */
- nsIdx = in.getInt();
- nameIdx = in.getInt();
- int flag = in.getInt();// 0x00140014 ?
- if (flag != 0x00140014) {
- throw new RuntimeException();
- }
- }
-
- attributeCount = in.getShort() & 0xFFFF;
- idAttribute = (in.getShort() & 0xFFFF) - 1;
- classAttribute = (in.getShort() & 0xFFFF) - 1;
- styleAttribute = (in.getShort() & 0xFFFF) - 1;
-
- attrs = in.asIntBuffer();
-
- // attrResId = new int[attributeCount];
- // attrName = new int[attributeCount];
- // attrNs = new int[attributeCount];
- // attrType = new int[attributeCount];
- // attrValue = new Object[attributeCount];
- // for (int i = 0; i < attributeCount; i++) {
- // int attrNsIdx = in.getInt();
- // int attrNameIdx = in.getInt();
- // int raw = in.getInt();
- // int aValueType = in.getInt() >>> 24;
- // int aValue = in.getInt();
- // Object value = null;
- // switch (aValueType) {
- // case TYPE_STRING:
- // value = strings[aValue];
- // break;
- // case TYPE_INT_BOOLEAN:
- // value = aValue != 0;
- // break;
- // default:
- // value = aValue;
- // }
- // int resourceId = attrNameIdx < this.resourceIds.length ?
- // resourceIds[attrNameIdx] : -1;
- // attrNs[i] = attrNsIdx;
- // attrName[i] = attrNameIdx;
- // attrType[i] = aValueType;
- // attrResId[i] = resourceId;
- // attrValue[i] = value;
- // }
- event = START_TAG;
- }
- break;
- case RES_XML_END_ELEMENT_TYPE: {
- in.position(p + size);
- event = END_TAG;
- }
- break;
- case RES_XML_START_NAMESPACE_TYPE:
- lineNumber = in.getInt();
- in.getInt();/* 0xFFFFFFFF */
- prefixIdx = in.getInt();
- nsIdx = in.getInt();
- event = START_NS;
- break;
- case RES_XML_END_NAMESPACE_TYPE:
- in.position(p + size);
- event = END_NS;
- break;
- case RES_STRING_POOL_TYPE:
- strings = StringItems.read(in);
- in.position(p + size);
- continue;
- case RES_XML_RESOURCE_MAP_TYPE:
- int count = size / 4 - 2;
- resourceIds = new int[count];
- for (int i = 0; i < count; i++) {
- resourceIds[i] = in.getInt();
- }
- in.position(p + size);
- continue;
- case RES_XML_CDATA_TYPE:
- lineNumber = in.getInt();
- in.getInt();/* 0xFFFFFFFF */
- textIdx = in.getInt();
-
- in.getInt();/* 00000008 00000000 */
- in.getInt();
-
- event = TEXT;
- break;
- default:
- throw new RuntimeException("Unsupported type: " + type);
- }
- in.position(p + size);
- return event;
- }
- return END_FILE;
- }
-}
diff --git a/core/src/main/java/pxb/android/axml/AxmlReader.java b/core/src/main/java/pxb/android/axml/AxmlReader.java
deleted file mode 100644
index 11c17613..00000000
--- a/core/src/main/java/pxb/android/axml/AxmlReader.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (c) 2009-2013 Panxiaobo
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package pxb.android.axml;
-
-import static pxb.android.axml.AxmlParser.END_FILE;
-import static pxb.android.axml.AxmlParser.END_NS;
-import static pxb.android.axml.AxmlParser.END_TAG;
-import static pxb.android.axml.AxmlParser.START_FILE;
-import static pxb.android.axml.AxmlParser.START_NS;
-import static pxb.android.axml.AxmlParser.START_TAG;
-import static pxb.android.axml.AxmlParser.TEXT;
-
-import java.io.IOException;
-import java.util.Stack;
-
-import de.robv.android.xposed.XposedBridge;
-
-/**
- * a class to read android axml
- *
- * @author Panxiaobo
- */
-public class AxmlReader {
- public static final NodeVisitor EMPTY_VISITOR = new NodeVisitor() {
-
- @Override
- public NodeVisitor child(String ns, String name) {
- return this;
- }
-
- };
- final AxmlParser parser;
-
- public AxmlReader(byte[] data) {
- super();
- this.parser = new AxmlParser(data);
- }
-
- public void accept(final AxmlVisitor av) throws IOException {
- Stack nvs = new Stack();
- NodeVisitor tos = av;
- while (true) {
- int type = parser.next();
- switch (type) {
- case START_FILE:
- break;
- case START_TAG:
- nvs.push(tos);
- tos = tos.child(parser.getNamespaceUri(), parser.getName());
- if (tos != null) {
- if (tos != EMPTY_VISITOR) {
- tos.line(parser.getLineNumber());
- for (int i = 0; i < parser.getAttrCount(); i++) {
- tos.attr(parser.getAttrNs(i), parser.getAttrName(i), parser.getAttrResId(i),
- parser.getAttrType(i), parser.getAttrValue(i));
- }
- }
- } else {
- tos = EMPTY_VISITOR;
- }
- break;
- case END_TAG:
- tos.end();
- tos = nvs.pop();
- break;
- case START_NS:
- av.ns(parser.getNamespacePrefix(), parser.getNamespaceUri(), parser.getLineNumber());
- break;
- case END_NS:
- break;
- case TEXT:
- tos.text(parser.getLineNumber(), parser.getText());
- break;
- case END_FILE:
- return;
- default:
- XposedBridge.log("Unsupported tag: " + type);
- }
- }
- }
-}
diff --git a/core/src/main/java/pxb/android/axml/AxmlVisitor.java b/core/src/main/java/pxb/android/axml/AxmlVisitor.java
deleted file mode 100644
index 3856d9d7..00000000
--- a/core/src/main/java/pxb/android/axml/AxmlVisitor.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2009-2013 Panxiaobo
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package pxb.android.axml;
-
-/**
- * visitor to visit an axml
- *
- * @author Panxiaobo
- */
-public class AxmlVisitor extends NodeVisitor {
-
- public AxmlVisitor() {
- super();
-
- }
-
- public AxmlVisitor(NodeVisitor av) {
- super(av);
- }
-
- /**
- * create a ns
- *
- * @param prefix
- * @param uri
- * @param ln
- */
- public void ns(String prefix, String uri, int ln) {
- if (nv != null && nv instanceof AxmlVisitor) {
- ((AxmlVisitor) nv).ns(prefix, uri, ln);
- }
- }
-
-}
diff --git a/core/src/main/java/pxb/android/axml/AxmlWriter.java b/core/src/main/java/pxb/android/axml/AxmlWriter.java
deleted file mode 100644
index d5daeedf..00000000
--- a/core/src/main/java/pxb/android/axml/AxmlWriter.java
+++ /dev/null
@@ -1,442 +0,0 @@
-/*
- * Copyright (c) 2009-2013 Panxiaobo
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package pxb.android.axml;
-
-import static pxb.android.ResConst.RES_STRING_POOL_TYPE;
-import static pxb.android.ResConst.RES_XML_CDATA_TYPE;
-import static pxb.android.ResConst.RES_XML_END_ELEMENT_TYPE;
-import static pxb.android.ResConst.RES_XML_END_NAMESPACE_TYPE;
-import static pxb.android.ResConst.RES_XML_RESOURCE_MAP_TYPE;
-import static pxb.android.ResConst.RES_XML_START_ELEMENT_TYPE;
-import static pxb.android.ResConst.RES_XML_START_NAMESPACE_TYPE;
-import static pxb.android.ResConst.RES_XML_TYPE;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.Stack;
-import java.util.TreeSet;
-
-import pxb.android.StringItem;
-import pxb.android.StringItems;
-
-/**
- * a class to write android axml
- *
- * @author Panxiaobo
- */
-public class AxmlWriter extends AxmlVisitor {
- static final Comparator ATTR_CMP = new Comparator() {
-
- @Override
- public int compare(Attr a, Attr b) {
- int x = a.resourceId - b.resourceId;
- if (x == 0) {
- x = a.name.data.compareTo(b.name.data);
- if (x == 0) {
- boolean aNsIsnull = a.ns == null;
- boolean bNsIsnull = b.ns == null;
- if (aNsIsnull) {
- if (bNsIsnull) {
- x = 0;
- } else {
- x = -1;
- }
- } else {
- if (bNsIsnull) {
- x = 1;
- } else {
- x = a.ns.data.compareTo(b.ns.data);
- }
- }
-
- }
- }
- return x;
- }
- };
-
- static class Attr {
-
- public int index;
- public StringItem name;
- public StringItem ns;
- public int resourceId;
- public int type;
- public Object value;
- public StringItem raw;
-
- public Attr(StringItem ns, StringItem name, int resourceId) {
- super();
- this.ns = ns;
- this.name = name;
- this.resourceId = resourceId;
- }
-
- public void prepare(AxmlWriter axmlWriter) {
- ns = axmlWriter.updateNs(ns);
- if (this.name != null) {
- if (resourceId != -1) {
- this.name = axmlWriter.updateWithResourceId(this.name, this.resourceId);
- } else {
- this.name = axmlWriter.update(this.name);
- }
- }
- if (value instanceof StringItem) {
- value = axmlWriter.update((StringItem) value);
- }
- if (raw != null) {
- raw = axmlWriter.update(raw);
- }
- }
-
- }
-
- static class NodeImpl extends NodeVisitor {
- private Set attrs = new TreeSet(ATTR_CMP);
- private List children = new ArrayList();
- private int line;
- private StringItem name;
- private StringItem ns;
- private StringItem text;
- private int textLineNumber;
- Attr id;
- Attr style;
- Attr clz;
-
- public NodeImpl(String ns, String name) {
- super(null);
- this.ns = ns == null ? null : new StringItem(ns);
- this.name = name == null ? null : new StringItem(name);
- }
-
- @Override
- public void attr(String ns, String name, int resourceId, int type, Object value) {
- if (name == null) {
- throw new RuntimeException("name can't be null");
- }
- Attr a = new Attr(ns == null ? null : new StringItem(ns), new StringItem(name), resourceId);
- a.type = type;
-
- if (value instanceof ValueWrapper) {
- ValueWrapper valueWrapper = (ValueWrapper) value;
- if (valueWrapper.raw != null) {
- a.raw = new StringItem(valueWrapper.raw);
- }
- a.value = valueWrapper.ref;
- switch (valueWrapper.type) {
- case ValueWrapper.CLASS:
- clz = a;
- break;
- case ValueWrapper.ID:
- id = a;
- break;
- case ValueWrapper.STYLE:
- style = a;
- break;
- }
- } else if (type == TYPE_STRING) {
- StringItem raw = new StringItem((String) value);
- a.raw = raw;
- a.value = raw;
-
- } else {
- a.raw = null;
- a.value = value;
- }
-
- attrs.add(a);
- }
-
- @Override
- public NodeVisitor child(String ns, String name) {
- NodeImpl child = new NodeImpl(ns, name);
- this.children.add(child);
- return child;
- }
-
- @Override
- public void end() {
- }
-
- @Override
- public void line(int ln) {
- this.line = ln;
- }
-
- public int prepare(AxmlWriter axmlWriter) {
- ns = axmlWriter.updateNs(ns);
- name = axmlWriter.update(name);
-
- int attrIndex = 0;
- for (Attr attr : attrs) {
- attr.index = attrIndex++;
- attr.prepare(axmlWriter);
- }
-
- text = axmlWriter.update(text);
- int size = 24 + 36 + attrs.size() * 20;// 24 for end tag,36+x*20 for
- // start tag
- for (NodeImpl child : children) {
- size += child.prepare(axmlWriter);
- }
- if (text != null) {
- size += 28;
- }
- return size;
- }
-
- @Override
- public void text(int ln, String value) {
- this.text = new StringItem(value);
- this.textLineNumber = ln;
- }
-
- void write(ByteBuffer out) throws IOException {
- // start tag
- out.putInt(RES_XML_START_ELEMENT_TYPE | (0x0010 << 16));
- out.putInt(36 + attrs.size() * 20);
- out.putInt(line);
- out.putInt(0xFFFFFFFF);
- out.putInt(ns != null ? this.ns.index : -1);
- out.putInt(name.index);
- out.putInt(0x00140014);// TODO
- out.putShort((short) this.attrs.size());
- out.putShort((short) (id == null ? 0 : id.index + 1));
- out.putShort((short) (clz == null ? 0 : clz.index + 1));
- out.putShort((short) (style == null ? 0 : style.index + 1));
- for (Attr attr : attrs) {
- out.putInt(attr.ns == null ? -1 : attr.ns.index);
- out.putInt(attr.name.index);
- out.putInt(attr.raw != null ? attr.raw.index : -1);
- out.putInt((attr.type << 24) | 0x000008);
- Object v = attr.value;
- if (v instanceof StringItem) {
- out.putInt(((StringItem) attr.value).index);
- } else if (v instanceof Boolean) {
- out.putInt(Boolean.TRUE.equals(v) ? -1 : 0);
- } else if (v instanceof Float) {
- out.putInt(Float.floatToIntBits((float) v));
- } else {
- out.putInt((Integer) attr.value);
- }
- }
-
- if (this.text != null) {
- out.putInt(RES_XML_CDATA_TYPE | (0x0010 << 16));
- out.putInt(28);
- out.putInt(textLineNumber);
- out.putInt(0xFFFFFFFF);
- out.putInt(text.index);
- out.putInt(0x00000008);
- out.putInt(0x00000000);
- }
-
- // children
- for (NodeImpl child : children) {
- child.write(out);
- }
-
- // end tag
- out.putInt(RES_XML_END_ELEMENT_TYPE | (0x0010 << 16));
- out.putInt(24);
- out.putInt(-1);
- out.putInt(0xFFFFFFFF);
- out.putInt(ns != null ? this.ns.index : -1);
- out.putInt(name.index);
- }
- }
-
- static class Ns {
- int ln;
- StringItem prefix;
- StringItem uri;
-
- public Ns(StringItem prefix, StringItem uri, int ln) {
- super();
- this.prefix = prefix;
- this.uri = uri;
- this.ln = ln;
- }
- }
-
- private List firsts = new ArrayList(3);
-
- private Map nses = new HashMap();
-
- private List otherString = new ArrayList();
-
- private Map resourceId2Str = new HashMap();
-
- private List resourceIds = new ArrayList();
-
- private List resourceString = new ArrayList();
-
- private StringItems stringItems = new StringItems();
-
- // TODO add style support
- // private List styleItems = new ArrayList();
-
- @Override
- public NodeVisitor child(String ns, String name) {
- NodeImpl first = new NodeImpl(ns, name);
- this.firsts.add(first);
- return first;
- }
-
- @Override
- public void end() {
- }
-
- @Override
- public void ns(String prefix, String uri, int ln) {
- nses.put(uri, new Ns(prefix == null ? null : new StringItem(prefix), new StringItem(uri), ln));
- }
-
- private int prepare() throws IOException {
- int size = 0;
-
- for (NodeImpl first : firsts) {
- size += first.prepare(this);
- }
- {
- int a = 0;
- for (Map.Entry