+ * Checks if a CharSequence is empty ("") or null. + *
+ * + *
+ * StringUtils.isEmpty(null) = true
+ * StringUtils.isEmpty("") = true
+ * StringUtils.isEmpty(" ") = false
+ * StringUtils.isEmpty("bob") = false
+ * StringUtils.isEmpty(" bob ") = false
+ *
+ *
+ * + * NOTE: This method changed in Lang version 2.0. It no longer trims the CharSequence. + * That functionality is available in isBlank(). + *
+ * @param cs the CharSequence to check, may be null + * @return {@code true} if the CharSequence is empty or null + * @since 3.0 Changed signature from isEmpty(String) to isEmpty(CharSequence) + */ + public static boolean isEmpty(final CharSequence cs) { + return cs == null || cs.length() == 0; + } + + /** + *+ * Checks if a CharSequence is not empty ("") and not null. + *
+ * + *
+ * StringUtils.isNotEmpty(null) = false
+ * StringUtils.isNotEmpty("") = false
+ * StringUtils.isNotEmpty(" ") = true
+ * StringUtils.isNotEmpty("bob") = true
+ * StringUtils.isNotEmpty(" bob ") = true
+ *
+ * @param cs the CharSequence to check, may be null
+ * @return {@code true} if the CharSequence is not empty and not null
+ * @since 3.0 Changed signature from isNotEmpty(String) to isNotEmpty(CharSequence)
+ */
+ public static boolean isNotEmpty(final CharSequence cs) {
+ return !isEmpty(cs);
+ }
+
+ /**
+ * + * Checks if a CharSequence is whitespace, empty ("") or null. + *
+ * + *
+ * StringUtils.isBlank(null) = true
+ * StringUtils.isBlank("") = true
+ * StringUtils.isBlank(" ") = true
+ * StringUtils.isBlank("bob") = false
+ * StringUtils.isBlank(" bob ") = false
+ *
+ * @param cs the CharSequence to check, may be null
+ * @return {@code true} if the CharSequence is null, empty or whitespace
+ */
+ public static boolean isBlank(final CharSequence cs) {
+ if (cs == null || cs.length() == 0) {
+ return true;
+ }
+ int strLen = cs.length();
+ for (int i = 0; i < strLen; i++) {
+ if (!Character.isWhitespace(cs.charAt(i))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * + * Checks if a CharSequence is not empty (""), not null and not whitespace only. + *
+ * + *+ * Whitespace is defined by {@link Character#isWhitespace(char)}. + *
+ * + *
+ * StringUtils.isNotBlank(null) = false
+ * StringUtils.isNotBlank("") = false
+ * StringUtils.isNotBlank(" ") = false
+ * StringUtils.isNotBlank("bob") = true
+ * StringUtils.isNotBlank(" bob ") = true
+ *
+ * @param cs the CharSequence to check, may be null
+ * @return {@code true} if the CharSequence is not empty and not null and not
+ * whitespace only
+ * @since 2.0
+ * @since 3.0 Changed signature from isNotBlank(String) to isNotBlank(CharSequence)
+ */
+ public static boolean isNotBlank(final CharSequence cs) {
+ return !isBlank(cs);
+ }
+
+ // Trim
+ // -----------------------------------------------------------------------
+
+ /**
+ * + * Removes control characters (char <= 32) from both ends of this String, handling + * {@code null} by returning {@code null}. + *
+ * + *+ * The String is trimmed using {@link String#trim()}. Trim removes start and end + * characters <= 32. + *
+ * + *
+ * StringUtils.trim(null) = null
+ * StringUtils.trim("") = ""
+ * StringUtils.trim(" ") = ""
+ * StringUtils.trim("abc") = "abc"
+ * StringUtils.trim(" abc ") = "abc"
+ *
+ * @param str the String to be trimmed, may be null
+ * @return the trimmed string, {@code null} if null String input
+ */
+ public static String trim(final String str) {
+ return str == null ? null : str.trim();
+ }
+
+ // Equals
+ // -----------------------------------------------------------------------
+
+ /**
+ * + * Compares two CharSequences, returning {@code true} if they represent equal + * sequences of characters. + *
+ * + *+ * {@code null}s are handled without exceptions. Two {@code null} references are + * considered to be equal. The comparison is case sensitive. + *
+ * + *
+ * StringUtils.equals(null, null) = true
+ * StringUtils.equals(null, "abc") = false
+ * StringUtils.equals("abc", null) = false
+ * StringUtils.equals("abc", "abc") = true
+ * StringUtils.equals("abc", "ABC") = false
+ *
+ * @param cs1 the first CharSequence, may be {@code null}
+ * @param cs2 the second CharSequence, may be {@code null}
+ * @return {@code true} if the CharSequences are equal (case-sensitive), or both
+ * {@code null}
+ * @see Object#equals(Object)
+ */
+ public static boolean equals(final CharSequence cs1, final CharSequence cs2) {
+ if (cs1 == cs2) {
+ return true;
+ }
+ if (cs1 == null || cs2 == null) {
+ return false;
+ }
+ if (cs1 instanceof String && cs2 instanceof String) {
+ return cs1.equals(cs2);
+ }
+ return StringUtils.regionMatches(cs1, false, 0, cs2, 0,
+ Math.max(cs1.length(), cs2.length()));
+ }
+
+ /**
+ * Green implementation of regionMatches.
+ * @param cs the {@code CharSequence} to be processed
+ * @param ignoreCase whether or not to be case insensitive
+ * @param thisStart the index to start on the {@code cs} CharSequence
+ * @param substring the {@code CharSequence} to be looked for
+ * @param start the index to start on the {@code substring} CharSequence
+ * @param length character length of the region
+ * @return whether the region matched
+ */
+ public static boolean regionMatches(final CharSequence cs, final boolean ignoreCase,
+ final int thisStart, final CharSequence substring, final int start,
+ final int length) {
+ if (cs instanceof String && substring instanceof String) {
+ return ((String) cs).regionMatches(ignoreCase, thisStart, (String) substring,
+ start, length);
+ }
+ int index1 = thisStart;
+ int index2 = start;
+ int tmpLen = length;
+
+ while (tmpLen-- > 0) {
+ final char c1 = cs.charAt(index1++);
+ final char c2 = substring.charAt(index2++);
+
+ if (c1 == c2) {
+ continue;
+ }
+
+ if (!ignoreCase) {
+ return false;
+ }
+
+ // The same check as in String.regionMatches():
+ if (Character.toUpperCase(c1) != Character.toUpperCase(c2)
+ && Character.toLowerCase(c1) != Character.toLowerCase(c2)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * + * Gets the substring after the first occurrence of a separator. The separator is not + * returned. + *
+ * + *
+ * A null string input will return null. An empty ("")
+ * string input will return the empty string. A null separator will
+ * return the empty string if the input string is not null.
+ *
+ * If nothing is found, the empty string is returned. + *
+ * + *
+ * StringUtils.substringAfter(null, *) = null
+ * StringUtils.substringAfter("", *) = ""
+ * StringUtils.substringAfter(*, null) = ""
+ * StringUtils.substringAfter("abc", "a") = "bc"
+ * StringUtils.substringAfter("abcba", "b") = "cba"
+ * StringUtils.substringAfter("abc", "c") = ""
+ * StringUtils.substringAfter("abc", "d") = ""
+ * StringUtils.substringAfter("abc", "") = "abc"
+ *
+ * @param str the String to get a substring from, may be null
+ * @param separator the String to search for, may be null
+ * @return the substring after the first occurrence of the separator,
+ * null if null String input
+ * @since 2.0
+ */
+ public static String substringAfter(String str, String separator) {
+ if (isEmpty(str)) {
+ return str;
+ }
+ if (separator == null) {
+ return EMPTY;
+ }
+ int pos = str.indexOf(separator);
+ if (pos == INDEX_NOT_FOUND) {
+ return EMPTY;
+ }
+ return str.substring(pos + separator.length());
+ }
+
+ // Substring between
+ // -----------------------------------------------------------------------
+ /**
+ * + * Gets the String that is nested in between two instances of the same String. + *
+ * + *
+ * A null input String returns null. A null tag
+ * returns null.
+ *
+ * StringUtils.substringBetween(null, *) = null
+ * StringUtils.substringBetween("", "") = ""
+ * StringUtils.substringBetween("", "tag") = null
+ * StringUtils.substringBetween("tagabctag", null) = null
+ * StringUtils.substringBetween("tagabctag", "") = ""
+ * StringUtils.substringBetween("tagabctag", "tag") = "abc"
+ *
+ * @param str the String containing the substring, may be null
+ * @param tag the String before and after the substring, may be null
+ * @return the substring, null if no match
+ * @since 2.0
+ */
+ public static String substringBetween(String str, String tag) {
+ return substringBetween(str, tag, tag);
+ }
+
+ /**
+ * + * Gets the String that is nested in between two Strings. Only the first match is + * returned. + *
+ * + *
+ * A null input String returns null. A null
+ * open/close returns null (no match). An empty ("") open and close
+ * returns an empty string.
+ *
+ * StringUtils.substringBetween("wx[b]yz", "[", "]") = "b"
+ * StringUtils.substringBetween(null, *, *) = null
+ * StringUtils.substringBetween(*, null, *) = null
+ * StringUtils.substringBetween(*, *, null) = null
+ * StringUtils.substringBetween("", "", "") = ""
+ * StringUtils.substringBetween("", "", "]") = null
+ * StringUtils.substringBetween("", "[", "]") = null
+ * StringUtils.substringBetween("yabcz", "", "") = ""
+ * StringUtils.substringBetween("yabcz", "y", "z") = "abc"
+ * StringUtils.substringBetween("yabczyabcz", "y", "z") = "abc"
+ *
+ * @param str the String containing the substring, may be null
+ * @param open the String before the substring, may be null
+ * @param close the String after the substring, may be null
+ * @return the substring, null if no match
+ * @since 2.0
+ */
+ public static String substringBetween(String str, String open, String close) {
+ if (str == null || open == null || close == null) {
+ return null;
+ }
+ int start = str.indexOf(open);
+ if (start != INDEX_NOT_FOUND) {
+ int end = str.indexOf(close, start + open.length());
+ if (end != INDEX_NOT_FOUND) {
+ return str.substring(start + open.length(), end);
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/pom.xml b/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/pom.xml
index 7f2550c2..080a35d0 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/pom.xml
+++ b/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/pom.xml
@@ -15,6 +15,10 @@