+ * From the Java documentation + * + * Standard charsets: + *
+ * @return An immutable, case-insensitive map from canonical charset names to charset + * objects. + * @see Charset#availableCharsets() + */ + public static SortedMap+ * Every implementation of the Java platform is required to support this character + * encoding. + *
+ * + * @see Standard + * charsets + * @deprecated Use Java 7's {@link java.nio.charset.StandardCharsets} + */ + @Deprecated + public static final Charset ISO_8859_1 = StandardCharsets.ISO_8859_1; + + /** + *+ * Seven-bit ASCII, also known as ISO646-US, also known as the Basic Latin block of + * the Unicode character set. + *
+ *+ * Every implementation of the Java platform is required to support this character + * encoding. + *
+ * + * @see Standard + * charsets + * @deprecated Use Java 7's {@link java.nio.charset.StandardCharsets} + */ + @Deprecated + public static final Charset US_ASCII = StandardCharsets.US_ASCII; + + /** + *+ * Sixteen-bit Unicode Transformation Format, The byte order specified by a mandatory + * initial byte-order mark (either order accepted on input, big-endian used on output) + *
+ *+ * Every implementation of the Java platform is required to support this character + * encoding. + *
+ * + * @see Standard + * charsets + * @deprecated Use Java 7's {@link java.nio.charset.StandardCharsets} + */ + @Deprecated + public static final Charset UTF_16 = StandardCharsets.UTF_16; + + /** + *+ * Sixteen-bit Unicode Transformation Format, big-endian byte order. + *
+ *+ * Every implementation of the Java platform is required to support this character + * encoding. + *
+ * + * @see Standard + * charsets + * @deprecated Use Java 7's {@link java.nio.charset.StandardCharsets} + */ + @Deprecated + public static final Charset UTF_16BE = StandardCharsets.UTF_16BE; + + /** + *+ * Sixteen-bit Unicode Transformation Format, little-endian byte order. + *
+ *+ * Every implementation of the Java platform is required to support this character + * encoding. + *
+ * + * @see Standard + * charsets + * @deprecated Use Java 7's {@link java.nio.charset.StandardCharsets} + */ + @Deprecated + public static final Charset UTF_16LE = StandardCharsets.UTF_16LE; + + /** + *+ * Eight-bit Unicode Transformation Format. + *
+ *+ * Every implementation of the Java platform is required to support this character + * encoding. + *
+ * + * @see Standard + * charsets + * @deprecated Use Java 7's {@link java.nio.charset.StandardCharsets} + */ + @Deprecated + public static final Charset UTF_8 = StandardCharsets.UTF_8; + +} diff --git a/spring-cloud-alibaba-starters/spring-cloud-alibaba-commons/src/main/java/com/alibaba/cloud/commons/io/FileUtils.java b/spring-cloud-alibaba-starters/spring-cloud-alibaba-commons/src/main/java/com/alibaba/cloud/commons/io/FileUtils.java new file mode 100644 index 00000000..0635edce --- /dev/null +++ b/spring-cloud-alibaba-starters/spring-cloud-alibaba-commons/src/main/java/com/alibaba/cloud/commons/io/FileUtils.java @@ -0,0 +1,113 @@ +/* + * Copyright 2013-2019 the original author or authors. + * + * 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 + * + * https://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 com.alibaba.cloud.commons.io; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.Charset; + +/** + * FileUtils. copy from apache commons-io. + * + * @author theonefx + */ +public final class FileUtils { + + private FileUtils() { + } + + // ----------------------------------------------------------------------- + /** + * Opens a {@link java.io.FileInputStream} for the specified file, providing better + * error messages than simply callingnew FileInputStream(file)
.
+ * + * At the end of the method either the stream will be successfully opened, or an + * exception will have been thrown. + *
+ * An exception is thrown if the file does not exist. An exception is thrown if the
+ * file object exists but is a directory. An exception is thrown if the file exists
+ * but cannot be read.
+ * @param file the file to open for input, must not be {@code null}
+ * @return a new {@link java.io.FileInputStream} for the specified file
+ * @throws java.io.FileNotFoundException if the file does not exist
+ * @throws IOException if the file object is a directory
+ * @throws IOException if the file cannot be read
+ * @since 1.3
+ */
+ public static FileInputStream openInputStream(final File file) throws IOException {
+ if (file.exists()) {
+ if (file.isDirectory()) {
+ throw new IOException("File '" + file + "' exists but is a directory");
+ }
+ if (!file.canRead()) {
+ throw new IOException("File '" + file + "' cannot be read");
+ }
+ }
+ else {
+ throw new FileNotFoundException("File '" + file + "' does not exist");
+ }
+ return new FileInputStream(file);
+ }
+
+ // -----------------------------------------------------------------------
+ /**
+ * Reads the contents of a file into a String. The file is always closed.
+ * @param file the file to read, must not be {@code null}
+ * @param encoding the encoding to use, {@code null} means platform default
+ * @return the file contents, never {@code null}
+ * @throws IOException in case of an I/O error
+ */
+ public static String readFileToString(final File file, final Charset encoding)
+ throws IOException {
+ try (InputStream in = openInputStream(file)) {
+ return IOUtils.toString(in, Charsets.toCharset(encoding));
+ }
+ }
+
+ /**
+ * Reads the contents of a file into a String. The file is always closed.
+ * @param file the file to read, must not be {@code null}
+ * @param encoding the encoding to use, {@code null} means platform default
+ * @return the file contents, never {@code null}
+ * @throws java.io.IOException in case of an I/O error
+ * @throws java.nio.charset.UnsupportedCharsetException thrown instead of
+ * {@link java.io .UnsupportedEncodingException} in version 2.2 if the encoding is not
+ * supported.
+ */
+ public static String readFileToString(final File file, final String encoding)
+ throws IOException {
+ return readFileToString(file, Charsets.toCharset(encoding));
+ }
+
+ /**
+ * Reads the contents of a file into a String using the default encoding for the VM.
+ * The file is always closed.
+ * @param file the file to read, must not be {@code null}
+ * @return the file contents, never {@code null}
+ * @throws IOException in case of an I/O error
+ * @deprecated 2.5 use {@link #readFileToString(File, String)} instead (and specify
+ * the appropriate encoding)
+ */
+ @Deprecated
+ public static String readFileToString(final File file) throws IOException {
+ return readFileToString(file, Charset.defaultCharset());
+ }
+
+}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-alibaba-commons/src/main/java/com/alibaba/cloud/commons/io/IOUtils.java b/spring-cloud-alibaba-starters/spring-cloud-alibaba-commons/src/main/java/com/alibaba/cloud/commons/io/IOUtils.java
new file mode 100644
index 00000000..85f61c5d
--- /dev/null
+++ b/spring-cloud-alibaba-starters/spring-cloud-alibaba-commons/src/main/java/com/alibaba/cloud/commons/io/IOUtils.java
@@ -0,0 +1,233 @@
+/*
+ * Copyright 2013-2019 the original author or authors.
+ *
+ * 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
+ *
+ * https://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 com.alibaba.cloud.commons.io;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Writer;
+import java.nio.charset.Charset;
+
+/**
+ * The IOUtils. copy from apache commons-io.
+ *
+ * @author theonefx
+ */
+public final class IOUtils {
+
+ /**
+ * Represents the end-of-file (or stream).
+ * @since 2.5 (made public)
+ */
+ public static final int EOF = -1;
+
+ /**
+ * The default buffer size ({@value}) to use for.
+ * {@link #copyLarge(InputStream, java.io.OutputStream)} and
+ * {@link #copyLarge(Reader, Writer)}
+ */
+ private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
+
+ private IOUtils() {
+
+ }
+
+ /**
+ * Gets the contents of an InputStream
as a String using the specified
+ * character encoding.
+ *
+ * This method buffers the input internally, so there is no need to use a
+ * BufferedInputStream
.
+ *
InputStream
to read from
+ * @param encoding the encoding to use, null means platform default
+ * @return the requested String
+ * @throws NullPointerException if the input is null
+ * @throws java.io.IOException if an I/O error occurs
+ * @since 2.3
+ */
+ public static String toString(final InputStream input, final Charset encoding)
+ throws IOException {
+ try (StringBuilderWriter sw = new StringBuilderWriter()) {
+ copy(input, sw, encoding);
+ return sw.toString();
+ }
+ }
+
+ // copy from Reader
+ // -----------------------------------------------------------------------
+
+ /**
+ * Copies chars from a Reader
to a Writer
.
+ *
+ * This method buffers the input internally, so there is no need to use a
+ * BufferedReader
.
+ *
+ * Large streams (over 2GB) will return a chars copied value of -1
after
+ * the copy has completed since the correct number of chars cannot be returned as an
+ * int. For large streams use the copyLarge(Reader, Writer)
method.
+ * @param input the Reader
to read from
+ * @param output the Writer
to write to
+ * @return the number of characters copied, or -1 if > Integer.MAX_VALUE
+ * @throws NullPointerException if the input or output is null
+ * @throws IOException if an I/O error occurs
+ * @since 1.1
+ */
+ public static int copy(final Reader input, final Writer output) throws IOException {
+ final long count = copyLarge(input, output);
+ if (count > Integer.MAX_VALUE) {
+ return -1;
+ }
+ return (int) count;
+ }
+
+ /**
+ * Copies bytes from an InputStream
to chars on a Writer
+ * using the specified character encoding.
+ *
+ * This method buffers the input internally, so there is no need to use a
+ * BufferedInputStream
.
+ *
+ * This method uses {@link java.io.InputStreamReader}.
+ * @param input the InputStream
to read from
+ * @param output the Writer
to write to
+ * @param inputEncoding the encoding to use for the input stream, null means platform
+ * default
+ * @throws NullPointerException if the input or output is null
+ * @throws IOException if an I/O error occurs
+ * @since 2.3
+ */
+ public static void copy(final InputStream input, final Writer output,
+ final Charset inputEncoding) throws IOException {
+ final InputStreamReader in = new InputStreamReader(input,
+ Charsets.toCharset(inputEncoding));
+ copy(in, output);
+ }
+
+ /**
+ * Copies bytes from an InputStream
to an OutputStream
using
+ * an internal buffer of the given size.
+ *
+ * This method buffers the input internally, so there is no need to use a
+ * BufferedInputStream
.
+ *
+ * @param input the InputStream
to read from
+ * @param output the OutputStream
to write to
+ * @param bufferSize the bufferSize used to copy from the input to the output
+ * @return the number of bytes copied
+ * @throws NullPointerException if the input or output is null
+ * @throws IOException if an I/O error occurs
+ * @since 2.5
+ */
+ public static long copy(final InputStream input, final OutputStream output,
+ final int bufferSize) throws IOException {
+ return copyLarge(input, output, new byte[bufferSize]);
+ }
+
+ /**
+ * Copies chars from a large (over 2GB) Reader
to a Writer
.
+ *
+ * This method buffers the input internally, so there is no need to use a
+ * BufferedReader
.
+ *
+ * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}.
+ * @param input the Reader
to read from
+ * @param output the Writer
to write to
+ * @return the number of characters copied
+ * @throws NullPointerException if the input or output is null
+ * @throws IOException if an I/O error occurs
+ * @since 1.3
+ */
+ public static long copyLarge(final Reader input, final Writer output)
+ throws IOException {
+ return copyLarge(input, output, new char[DEFAULT_BUFFER_SIZE]);
+ }
+
+ /**
+ * Copies chars from a large (over 2GB) Reader
to a Writer
.
+ *
+ * This method uses the provided buffer, so there is no need to use a
+ * BufferedReader
.
+ *
+ * @param input the Reader
to read from
+ * @param output the Writer
to write to
+ * @param buffer the buffer to be used for the copy
+ * @return the number of characters copied
+ * @throws NullPointerException if the input or output is null
+ * @throws IOException if an I/O error occurs
+ * @since 2.2
+ */
+ public static long copyLarge(final Reader input, final Writer output,
+ final char[] buffer) throws IOException {
+ long count = 0;
+ int n;
+ while (EOF != (n = input.read(buffer))) {
+ output.write(buffer, 0, n);
+ count += n;
+ }
+ return count;
+ }
+
+ /**
+ * Copies bytes from a large (over 2GB) InputStream
to an
+ * OutputStream
.
+ *
+ * This method buffers the input internally, so there is no need to use a
+ * BufferedInputStream
.
+ *
+ * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}.
+ * @param input the InputStream
to read from
+ * @param output the OutputStream
to write to
+ * @return the number of bytes copied
+ * @throws NullPointerException if the input or output is null
+ * @throws IOException if an I/O error occurs
+ * @since 1.3
+ */
+ public static long copyLarge(final InputStream input, final OutputStream output)
+ throws IOException {
+ return copy(input, output, DEFAULT_BUFFER_SIZE);
+ }
+
+ /**
+ * Copies bytes from a large (over 2GB) InputStream
to an
+ * OutputStream
.
+ *
+ * This method uses the provided buffer, so there is no need to use a
+ * BufferedInputStream
.
+ *
+ * @param input the InputStream
to read from
+ * @param output the OutputStream
to write to
+ * @param buffer the buffer to use for the copy
+ * @return the number of bytes copied
+ * @throws NullPointerException if the input or output is null
+ * @throws IOException if an I/O error occurs
+ * @since 2.2
+ */
+ public static long copyLarge(final InputStream input, final OutputStream output,
+ final byte[] buffer) throws IOException {
+ long count = 0;
+ int n;
+ while (EOF != (n = input.read(buffer))) {
+ output.write(buffer, 0, n);
+ count += n;
+ }
+ return count;
+ }
+
+}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-alibaba-commons/src/main/java/com/alibaba/cloud/commons/io/StringBuilderWriter.java b/spring-cloud-alibaba-starters/spring-cloud-alibaba-commons/src/main/java/com/alibaba/cloud/commons/io/StringBuilderWriter.java
new file mode 100644
index 00000000..9a057816
--- /dev/null
+++ b/spring-cloud-alibaba-starters/spring-cloud-alibaba-commons/src/main/java/com/alibaba/cloud/commons/io/StringBuilderWriter.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2013-2019 the original author or authors.
+ *
+ * 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
+ *
+ * https://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 com.alibaba.cloud.commons.io;
+
+import java.io.Serializable;
+import java.io.Writer;
+
+/**
+ * Copy from apache commons-io.
+ *
+ * @author theonefx
+ */
+public class StringBuilderWriter extends Writer implements Serializable {
+
+ private static final long serialVersionUID = -146927496096066153L;
+
+ private final StringBuilder builder;
+
+ /**
+ * Constructs a new {@link StringBuilder} instance with default capacity.
+ */
+ public StringBuilderWriter() {
+ this.builder = new StringBuilder();
+ }
+
+ /**
+ * Constructs a new {@link StringBuilder} instance with the specified capacity.
+ * @param capacity The initial capacity of the underlying {@link StringBuilder}
+ */
+ public StringBuilderWriter(final int capacity) {
+ this.builder = new StringBuilder(capacity);
+ }
+
+ /**
+ * Constructs a new instance with the specified {@link StringBuilder}.
+ *
+ *
+ * If {@code builder} is null a new instance with default capacity will be created. + *
+ * @param builder The String builder. May be null. + */ + public StringBuilderWriter(final StringBuilder builder) { + this.builder = builder != null ? builder : new StringBuilder(); + } + + /** + * Appends a single character to this Writer. + * @param value The character to append + * @return This writer instance + */ + @Override + public Writer append(final char value) { + builder.append(value); + return this; + } + + /** + * Appends a character sequence to this Writer. + * @param value The character to append + * @return This writer instance + */ + @Override + public Writer append(final CharSequence value) { + builder.append(value); + return this; + } + + /** + * Appends a portion of a character sequence to the {@link StringBuilder}. + * @param value The character to append + * @param start The index of the first character + * @param end The index of the last character + 1 + * @return This writer instance + */ + @Override + public Writer append(final CharSequence value, final int start, final int end) { + builder.append(value, start, end); + return this; + } + + /** + * Closing this writer has no effect. + */ + @Override + public void close() { + // no-op + } + + /** + * Flushing this writer has no effect. + */ + @Override + public void flush() { + // no-op + } + + /** + * Writes a String to the {@link StringBuilder}. + * @param value The value to write + */ + @Override + public void write(final String value) { + if (value != null) { + builder.append(value); + } + } + + /** + * Writes a portion of a character array to the {@link StringBuilder}. + * @param value The value to write + * @param offset The index of the first character + * @param length The number of characters to write + */ + @Override + public void write(final char[] value, final int offset, final int length) { + if (value != null) { + builder.append(value, offset, length); + } + } + + /** + * Returns the underlying builder. + * @return The underlying builder + */ + public StringBuilder getBuilder() { + return builder; + } + + /** + * Returns {@link StringBuilder#toString()}. + * @return The contents of the String builder. + */ + @Override + public String toString() { + return builder.toString(); + } + +} diff --git a/spring-cloud-alibaba-starters/spring-cloud-alibaba-commons/src/main/java/com/alibaba/cloud/commons/lang/StringUtils.java b/spring-cloud-alibaba-starters/spring-cloud-alibaba-commons/src/main/java/com/alibaba/cloud/commons/lang/StringUtils.java new file mode 100644 index 00000000..d9c15136 --- /dev/null +++ b/spring-cloud-alibaba-starters/spring-cloud-alibaba-commons/src/main/java/com/alibaba/cloud/commons/lang/StringUtils.java @@ -0,0 +1,372 @@ +/* + * Copyright 2013-2019 the original author or authors. + * + * 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 + * + * https://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 com.alibaba.cloud.commons.lang; + +/** + * StringUtils. copy from apache common-lang3. + * + * @author theonefx + */ +public final class StringUtils { + + /** + * The empty String {@code ""}. + * + * @since 2.0 + */ + public static final String EMPTY = ""; + + /** + * Represents a failed index search. + * @since 2.1 + */ + public static final int INDEX_NOT_FOUND = -1; + + private StringUtils() { + } + + /** + *+ * 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 3316d7bd..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 @@