Merge remote-tracking branch 'APACHE/master'

This commit is contained in:
MarkDacek 2017-03-17 17:43:15 -04:00
commit 40b8ecd3fa
15 changed files with 423 additions and 194 deletions

View File

@ -21,5 +21,8 @@ jdk:
- oraclejdk7
- oraclejdk8
script:
- mvn test checkstyle:check javadoc:javadoc apache-rat:check -B
after_success:
- mvn clean apache-rat:check cobertura:cobertura coveralls:report
- mvn clean cobertura:cobertura coveralls:report

View File

@ -36,11 +36,10 @@ limitations under the License.
<module name="RedundantImport"/>
<module name="UnusedImports"/>
<module name="NeedBraces"/>
<module name="RedundantThrows">
<property name="allowUnchecked" value="true"/>
</module>
<module name="JavadocMethod">
<property name="allowUndeclaredRTE" value="true"/>
<property name="scope" value="public" />
</module>
<module name="UpperEll" />
</module>
</module>

16
pom.xml
View File

@ -22,7 +22,7 @@
<parent>
<groupId>org.apache.commons</groupId>
<artifactId>commons-parent</artifactId>
<version>41</version>
<version>42</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>commons-lang3</artifactId>
@ -502,6 +502,9 @@
<contributor>
<name>Adrian Ber</name>
</contributor>
<contributor>
<name>Mark Dacek</name>
</contributor>
</contributors>
<!-- Lang should depend on very little -->
@ -576,6 +579,7 @@
<!-- Override clirr version to be able to build the site on Java 8 -->
<commons.clirr.version>2.8</commons.clirr.version>
<checkstyle.plugin.version>2.17</checkstyle.plugin.version>
</properties>
@ -646,6 +650,14 @@
</ignorePathsToDelete>
</configuration>
</plugin>
<plugin>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>${checkstyle.plugin.version}</version>
<configuration>
<configLocation>${basedir}/checkstyle.xml</configLocation>
<enableRulesSummary>false</enableRulesSummary>
</configuration>
</plugin>
</plugins>
</build>
@ -654,7 +666,7 @@
<plugins>
<plugin>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>2.15</version>
<version>${checkstyle.plugin.version}</version>
<configuration>
<configLocation>${basedir}/checkstyle.xml</configLocation>
<enableRulesSummary>false</enableRulesSummary>

View File

@ -46,6 +46,7 @@ The <action> type attribute can be add,update,fix,remove.
<body>
<release version="3.6" date="2017-MM-DD" description="TBD">
<action issue="LANG-1300" type="fix" dev="chtompki" due-to="Mark Dacek">Clarify or improve behaviour of int-based indexOf methods in StringUtils</action>
<action issue="LANG-1299" type="add" dev="djones">Add method for converting string to an array of code points</action>
<action issue="LANG-1286" type="fix" dev="djones">RandomStringUtils random method can overflow and return characters outside of specified range</action>
<action issue="LANG-660" type="add" dev="djones">Add methods to insert arrays into arrays at an index</action>
@ -66,7 +67,7 @@ The <action> type attribute can be add,update,fix,remove.
<action issue="LANG-740" type="add" dev="pschumacher" due-to="James Sawle">Implementation of a Memomizer</action>
<action issue="LANG-1258" type="add" dev="pschumacher" due-to="IG, Grzegorz Rożniecki">Add ArrayUtils#toStringArray method</action>
<action issue="LANG-1160" type="add" dev="kinow">StringUtils#abbreviate should support 'custom ellipses' parameter</action>
<action issue="LANG-1270" type="add" dev="pschumacher" due-to="Pierre Templier">Add StringUtils#isAnyNotEmpty and #isAnyNotBlank</action>
<action issue="LANG-1293" type="add" dev="pschumacher" due-to="Pierre Templier, Martin Tarjanyi">Add StringUtils#isAllEmpty and #isAllBlank methods</action>
<action issue="LANG-1291" type="add" dev="ggregory">Provide annotations to document thread safety</action>
<action issue="LANG-1290" type="update" dev="pschumacher" due-to="Andrii Abramov">Increase test coverage of org.apache.commons.lang3.ArrayUtils</action>
<action issue="LANG-1274" type="update" dev="pschumacher">StrSubstitutor should state its thread safety</action>
@ -78,6 +79,7 @@ The <action> type attribute can be add,update,fix,remove.
<action issue="LANG-1311" type="fix" dev="pschumacher" due-to="Aaron Digulla">TypeUtils.toString() doesn't handle primitive and Object arrays correctly</action>
<action issue="LANG-1312" type="fix" dev="pschumacher">LocaleUtils#toLocale does not support language followed by UN M.49 numeric-3 area code</action>
<action issue="LANG-1265" type="fix" dev="pschumacher">Build failures when building with Java 9 EA</action>
<action issue="LANG-1314" type="fix" dev="pschumacher" due-to="Allon Murienik">javadoc creation broken with Java 8</action>
</release>
<release version="3.5" date="2016-10-13" description="New features including Java 9 detection">

View File

@ -8409,6 +8409,7 @@ public class ArrayUtils {
* ArrayUtils.insert(index, null, values) = null
* </pre>
*
* @param <T> The type of elements in {@code array} and {@code values}
* @param index the position within {@code array} to insert the new values
* @param array the array to insert the values into, may be {@code null}
* @param values the new values to insert, may be {@code null}

View File

@ -59,13 +59,42 @@ public class CharSequenceUtils {
//-----------------------------------------------------------------------
/**
* <p>Finds the first index in the {@code CharSequence} that matches the
* specified character.</p>
* Returns the index within <code>cs</code> of the first occurrence of the
* specified character, starting the search at the specified index.
* <p>
* If a character with value <code>searchChar</code> occurs in the
* character sequence represented by the <code>cs</code>
* object at an index no smaller than <code>start</code>, then
* the index of the first such occurrence is returned. For values
* of <code>searchChar</code> in the range from 0 to 0xFFFF (inclusive),
* this is the smallest value <i>k</i> such that:
* <blockquote><pre>
* (this.charAt(<i>k</i>) == searchChar) &amp;&amp; (<i>k</i> &gt;= start)
* </pre></blockquote>
* is true. For other values of <code>searchChar</code>, it is the
* smallest value <i>k</i> such that:
* <blockquote><pre>
* (this.codePointAt(<i>k</i>) == searchChar) &amp;&amp; (<i>k</i> &gt;= start)
* </pre></blockquote>
* is true. In either case, if no such character occurs inm <code>cs</code>
* at or after position <code>start</code>, then
* <code>-1</code> is returned.
*
* <p>
* There is no restriction on the value of <code>start</code>. If it
* is negative, it has the same effect as if it were zero: the entire
* <code>CharSequence</code> may be searched. If it is greater than
* the length of <code>cs</code>, it has the same effect as if it were
* equal to the length of <code>cs</code>: <code>-1</code> is returned.
*
* <p>All indices are specified in <code>char</code> values
* (Unicode code units).
*
* @param cs the {@code CharSequence} to be processed, not null
* @param searchChar the char to be searched for
* @param start the start index, negative starts at the string start
* @return the index where the search char was found, -1 if not found
* @since 3.6 updated to behave more like <code>String</code>
*/
static int indexOf(final CharSequence cs, final int searchChar, int start) {
if (cs instanceof String) {
@ -75,9 +104,22 @@ public class CharSequenceUtils {
if (start < 0) {
start = 0;
}
for (int i = start; i < sz; i++) {
if (cs.charAt(i) == searchChar) {
return i;
if (searchChar < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
for (int i = start; i < sz; i++) {
if (cs.charAt(i) == searchChar) {
return i;
}
}
}
//supplementary characters (LANG1300)
if (searchChar <= Character.MAX_CODE_POINT) {
char[] chars = Character.toChars(searchChar);
for (int i = start; i < sz - 1; i++) {
char high = cs.charAt(i);
char low = cs.charAt(i + 1);
if (high == chars[0] && low == chars[1]) {
return i;
}
}
}
return NOT_FOUND;
@ -105,13 +147,30 @@ public class CharSequenceUtils {
}
/**
* <p>Finds the last index in the {@code CharSequence} that matches the
* specified character.</p>
* Returns the index within <code>cs</code> of the last occurrence of
* the specified character, searching backward starting at the
* specified index. For values of <code>searchChar</code> in the range
* from 0 to 0xFFFF (inclusive), the index returned is the largest
* value <i>k</i> such that:
* <blockquote><pre>
* (this.charAt(<i>k</i>) == searchChar) &amp;&amp; (<i>k</i> &lt;= start)
* </pre></blockquote>
* is true. For other values of <code>searchChar</code>, it is the
* largest value <i>k</i> such that:
* <blockquote><pre>
* (this.codePointAt(<i>k</i>) == searchChar) &amp;&amp; (<i>k</i> &lt;= start)
* </pre></blockquote>
* is true. In either case, if no such character occurs in <code>cs</code>
* at or before position <code>start</code>, then <code>-1</code> is returned.
*
* <p>All indices are specified in <code>char</code> values
* (Unicode code units).
*
* @param cs the {@code CharSequence} to be processed
* @param searchChar the char to be searched for
* @param start the start index, negative returns -1, beyond length starts at end
* @return the index where the search char was found, -1 if not found
* @since 3.6 updated to behave more like <code>String</code>
*/
static int lastIndexOf(final CharSequence cs, final int searchChar, int start) {
if (cs instanceof String) {
@ -124,9 +183,27 @@ public class CharSequenceUtils {
if (start >= sz) {
start = sz - 1;
}
for (int i = start; i >= 0; --i) {
if (cs.charAt(i) == searchChar) {
return i;
if (searchChar < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
for (int i = start; i >= 0; --i) {
if (cs.charAt(i) == searchChar) {
return i;
}
}
}
//supplementary characters (LANG1300)
//NOTE - we must do a forward traversal for this to avoid duplicating code points
if (searchChar <= Character.MAX_CODE_POINT) {
char[] chars = Character.toChars(searchChar);
//make sure it's not the last index
if (start == sz - 1) {
return NOT_FOUND;
}
for (int i = start; i >= 0; i--) {
char high = cs.charAt(i);
char low = cs.charAt(i + 1);
if (chars[0] == high && chars[1] == low) {
return i;
}
}
}
return NOT_FOUND;

View File

@ -258,36 +258,6 @@ public class StringUtils {
return false;
}
/**
* <p>Checks if any of the CharSequences are not empty ("") and not null.</p>
*
* <pre>
* StringUtils.isAnyNotEmpty(null) = false
* StringUtils.isAnyNotEmpty(new String[] {}) = false
* StringUtils.isAnyNotEmpty(null, "foo") = true
* StringUtils.isAnyNotEmpty("", "bar") = true
* StringUtils.isAnyNotEmpty("bob", "") = true
* StringUtils.isAnyNotEmpty(" bob ", null) = true
* StringUtils.isAnyNotEmpty(" ", "bar") = true
* StringUtils.isAnyNotEmpty("foo", "bar") = true
* </pre>
*
* @param css the CharSequences to check, may be null or empty
* @return {@code true} if any of the CharSequences are not empty and not null
* @since 3.6
*/
public static boolean isAnyNotEmpty(final CharSequence... css) {
if (ArrayUtils.isEmpty(css)) {
return false;
}
for (final CharSequence cs : css) {
if (isNotEmpty(cs)) {
return true;
}
}
return false;
}
/**
* <p>Checks if none of the CharSequences are empty ("") or null.</p>
*
@ -310,10 +280,41 @@ public class StringUtils {
return !isAnyEmpty(css);
}
/**
* <p>Checks if all of the CharSequences are empty ("") or null.</p>
*
* <pre>
* StringUtils.isAllEmpty(null) = true
* StringUtils.isAllEmpty(null, "") = true
* StringUtils.isAllEmpty(new String[] {}) = true
* StringUtils.isAllEmpty(null, "foo") = false
* StringUtils.isAllEmpty("", "bar") = false
* StringUtils.isAllEmpty("bob", "") = false
* StringUtils.isAllEmpty(" bob ", null) = false
* StringUtils.isAllEmpty(" ", "bar") = false
* StringUtils.isAllEmpty("foo", "bar") = false
* </pre>
*
* @param css the CharSequences to check, may be null or empty
* @return {@code true} if all of the CharSequences are empty or null
* @since 3.6
*/
public static boolean isAllEmpty(final CharSequence... css) {
if (ArrayUtils.isEmpty(css)) {
return true;
}
for (final CharSequence cs : css) {
if (isNotEmpty(cs)) {
return false;
}
}
return true;
}
/**
* <p>Checks if a CharSequence is empty (""), null or whitespace only.</p>
*
* </p>Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
* <p>Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
*
* <pre>
* StringUtils.isBlank(null) = true
@ -344,7 +345,7 @@ public class StringUtils {
/**
* <p>Checks if a CharSequence is not empty (""), not null and not whitespace only.</p>
*
* </p>Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
* <p>Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
*
* <pre>
* StringUtils.isNotBlank(null) = false
@ -367,7 +368,7 @@ public class StringUtils {
/**
* <p>Checks if any of the CharSequences are empty ("") or null or whitespace only.</p>
*
* </p>Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
* <p>Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
*
* <pre>
* StringUtils.isAnyBlank(null) = true
@ -397,43 +398,10 @@ public class StringUtils {
return false;
}
/**
* <p>Checks if any of the CharSequences are not empty (""), not null and not whitespace only.</p>
*
* </p>Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
*
* <pre>
* StringUtils.isAnyNotBlank(null) = false
* StringUtils.isAnyNotBlank(null, "foo") = true
* StringUtils.isAnyNotBlank(null, null) = false
* StringUtils.isAnyNotBlank("", "bar") = true
* StringUtils.isAnyNotBlank("bob", "") = true
* StringUtils.isAnyNotBlank(" bob ", null) = true
* StringUtils.isAnyNotBlank(" ", "bar") = true
* StringUtils.isAnyNotBlank("foo", "bar") = true
* StringUtils.isAnyNotBlank(new String[] {}) = false
* </pre>
*
* @param css the CharSequences to check, may be null or empty
* @return {@code true} if any of the CharSequences are not empty and not null and not whitespace only
* @since 3.6
*/
public static boolean isAnyNotBlank(final CharSequence... css) {
if (ArrayUtils.isEmpty(css)) {
return false;
}
for (final CharSequence cs : css) {
if (isNotBlank(cs)) {
return true;
}
}
return false;
}
/**
* <p>Checks if none of the CharSequences are empty (""), null or whitespace only.</p>
*
* </p>Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
* <p>Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
*
* <pre>
* StringUtils.isNoneBlank(null) = false
@ -455,6 +423,39 @@ public class StringUtils {
return !isAnyBlank(css);
}
/**
* <p>Checks if all of the CharSequences are empty (""), null or whitespace only.</p>
*
* <p>Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
*
* <pre>
* StringUtils.isAllBlank(null) = true
* StringUtils.isAllBlank(null, "foo") = false
* StringUtils.isAllBlank(null, null) = true
* StringUtils.isAllBlank("", "bar") = false
* StringUtils.isAllBlank("bob", "") = false
* StringUtils.isAllBlank(" bob ", null) = false
* StringUtils.isAllBlank(" ", "bar") = false
* StringUtils.isAllBlank("foo", "bar") = false
* StringUtils.isAllBlank(new String[] {}) = true
* </pre>
*
* @param css the CharSequences to check, may be null or empty
* @return {@code true} if all of the CharSequences are empty or null or whitespace only
* @since 3.6
*/
public static boolean isAllBlank(final CharSequence... css) {
if (ArrayUtils.isEmpty(css)) {
return true;
}
for (final CharSequence cs : css) {
if (isNotBlank(cs)) {
return false;
}
}
return true;
}
// Trim
//-----------------------------------------------------------------------
/**
@ -1275,10 +1276,26 @@ public class StringUtils {
// IndexOf
//-----------------------------------------------------------------------
/**
* <p>Finds the first index within a CharSequence, handling {@code null}.
* This method uses {@link String#indexOf(int, int)} if possible.</p>
* Returns the index within <code>seq</code> of the first occurrence of
* the specified character. If a character with value
* <code>searchChar</code> occurs in the character sequence represented by
* <code>seq</code> <code>CharSequence</code> object, then the index (in Unicode
* code units) of the first such occurrence is returned. For
* values of <code>searchChar</code> in the range from 0 to 0xFFFF
* (inclusive), this is the smallest value <i>k</i> such that:
* <blockquote><pre>
* this.charAt(<i>k</i>) == searchChar
* </pre></blockquote>
* is true. For other values of <code>searchChar</code>, it is the
* smallest value <i>k</i> such that:
* <blockquote><pre>
* this.codePointAt(<i>k</i>) == searchChar
* </pre></blockquote>
* is true. In either case, if no such character occurs in <code>seq</code>,
* then {@code INDEX_NOT_FOUND (-1)} is returned.
*
* <p>A {@code null} or empty ("") CharSequence will return {@code INDEX_NOT_FOUND (-1)}.</p>
* <p>Furthermore, a {@code null} or empty ("") CharSequence will
* return {@code INDEX_NOT_FOUND (-1)}.</p>
*
* <pre>
* StringUtils.indexOf(null, *) = -1
@ -1293,6 +1310,7 @@ public class StringUtils {
* -1 if no match or {@code null} string input
* @since 2.0
* @since 3.0 Changed signature from indexOf(String, int) to indexOf(CharSequence, int)
* @since 3.6 Updated {@link CharSequenceUtils} call to behave more like <code>String</code>
*/
public static int indexOf(final CharSequence seq, final int searchChar) {
if (isEmpty(seq)) {
@ -1302,13 +1320,39 @@ public class StringUtils {
}
/**
* <p>Finds the first index within a CharSequence from a start position,
* handling {@code null}.
* This method uses {@link String#indexOf(int, int)} if possible.</p>
*
* <p>A {@code null} or empty ("") CharSequence will return {@code (INDEX_NOT_FOUND) -1}.
* A negative start position is treated as zero.
* A start position greater than the string length returns {@code -1}.</p>
* Returns the index within <code>seq</code> of the first occurrence of the
* specified character, starting the search at the specified index.
* <p>
* If a character with value <code>searchChar</code> occurs in the
* character sequence represented by the <code>seq</code> <code>CharSequence</code>
* object at an index no smaller than <code>startPos</code>, then
* the index of the first such occurrence is returned. For values
* of <code>searchChar</code> in the range from 0 to 0xFFFF (inclusive),
* this is the smallest value <i>k</i> such that:
* <blockquote><pre>
* (this.charAt(<i>k</i>) == searchChar) &amp;&amp; (<i>k</i> &gt;= startPos)
* </pre></blockquote>
* is true. For other values of <code>searchChar</code>, it is the
* smallest value <i>k</i> such that:
* <blockquote><pre>
* (this.codePointAt(<i>k</i>) == searchChar) &amp;&amp; (<i>k</i> &gt;= startPos)
* </pre></blockquote>
* is true. In either case, if no such character occurs in <code>seq</code>
* at or after position <code>startPos</code>, then
* <code>-1</code> is returned.
*
* <p>
* There is no restriction on the value of <code>startPos</code>. If it
* is negative, it has the same effect as if it were zero: this entire
* string may be searched. If it is greater than the length of this
* string, it has the same effect as if it were equal to the length of
* this string: {@code (INDEX_NOT_FOUND) -1} is returned. Furthermore, a
* {@code null} or empty ("") CharSequence will
* return {@code (INDEX_NOT_FOUND) -1}.
*
* <p>All indices are specified in <code>char</code> values
* (Unicode code units).
*
* <pre>
* StringUtils.indexOf(null, *, *) = -1
@ -1326,6 +1370,7 @@ public class StringUtils {
* -1 if no match or {@code null} string input
* @since 2.0
* @since 3.0 Changed signature from indexOf(String, int, int) to indexOf(CharSequence, int, int)
* @since 3.6 Updated {@link CharSequenceUtils} call to behave more like <code>String</code>
*/
public static int indexOf(final CharSequence seq, final int searchChar, final int startPos) {
if (isEmpty(seq)) {
@ -1585,10 +1630,23 @@ public class StringUtils {
// LastIndexOf
//-----------------------------------------------------------------------
/**
* <p>Finds the last index within a CharSequence, handling {@code null}.
* This method uses {@link String#lastIndexOf(int)} if possible.</p>
*
* <p>A {@code null} or empty ("") CharSequence will return {@code -1}.</p>
* Returns the index within <code>seq</code> of the last occurrence of
* the specified character. For values of <code>searchChar</code> in the
* range from 0 to 0xFFFF (inclusive), the index (in Unicode code
* units) returned is the largest value <i>k</i> such that:
* <blockquote><pre>
* this.charAt(<i>k</i>) == searchChar
* </pre></blockquote>
* is true. For other values of <code>searchChar</code>, it is the
* largest value <i>k</i> such that:
* <blockquote><pre>
* this.codePointAt(<i>k</i>) == searchChar
* </pre></blockquote>
* is true. In either case, if no such character occurs in this
* string, then <code>-1</code> is returned. Furthermore, a {@code null} or empty ("")
* <code>CharSequence</code> will return {@code -1}. The
* <code>seq</code> <code>CharSequence</code> object is searched backwards
* starting at the last character.
*
* <pre>
* StringUtils.lastIndexOf(null, *) = -1
@ -1597,12 +1655,13 @@ public class StringUtils {
* StringUtils.lastIndexOf("aabaabaa", 'b') = 5
* </pre>
*
* @param seq the CharSequence to check, may be null
* @param seq the <code>CharSequence</code> to check, may be null
* @param searchChar the character to find
* @return the last index of the search character,
* -1 if no match or {@code null} string input
* @since 2.0
* @since 3.0 Changed signature from lastIndexOf(String, int) to lastIndexOf(CharSequence, int)
* @since 3.6 Updated {@link CharSequenceUtils} call to behave more like <code>String</code>
*/
public static int lastIndexOf(final CharSequence seq, final int searchChar) {
if (isEmpty(seq)) {
@ -1612,16 +1671,29 @@ public class StringUtils {
}
/**
* <p>Finds the last index within a CharSequence from a start position,
* handling {@code null}.
* This method uses {@link String#lastIndexOf(int, int)} if possible.</p>
* Returns the index within <code>seq</code> of the last occurrence of
* the specified character, searching backward starting at the
* specified index. For values of <code>searchChar</code> in the range
* from 0 to 0xFFFF (inclusive), the index returned is the largest
* value <i>k</i> such that:
* <blockquote><pre>
* (this.charAt(<i>k</i>) == searchChar) &amp;&amp; (<i>k</i> &lt;= startPos)
* </pre></blockquote>
* is true. For other values of <code>searchChar</code>, it is the
* largest value <i>k</i> such that:
* <blockquote><pre>
* (this.codePointAt(<i>k</i>) == searchChar) &amp;&amp; (<i>k</i> &lt;= startPos)
* </pre></blockquote>
* is true. In either case, if no such character occurs in <code>seq</code>
* at or before position <code>startPos</code>, then
* <code>-1</code> is returned. Furthermore, a {@code null} or empty ("")
* <code>CharSequence</code> will return {@code -1}. A start position greater
* than the string length searches the whole string.
* The search starts at the <code>startPos</code> and works backwards;
* matches starting after the start position are ignored.
*
* <p>A {@code null} or empty ("") CharSequence will return {@code -1}.
* A negative start position returns {@code -1}.
* A start position greater than the string length searches the whole string.
* The search starts at the startPos and works backwards; matches starting after the start
* position are ignored.
* </p>
* <p>All indices are specified in <code>char</code> values
* (Unicode code units).
*
* <pre>
* StringUtils.lastIndexOf(null, *, *) = -1
@ -1943,7 +2015,7 @@ public class StringUtils {
/**
* <p>Check whether the given CharSequence contains any whitespace characters.</p>
*
* </p>Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
* <p>Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
*
* @param seq the CharSequence to check (may be {@code null})
* @return {@code true} if the CharSequence is not empty and
@ -2461,7 +2533,6 @@ public class StringUtils {
if (str == null || searchStrs == null) {
return INDEX_NOT_FOUND;
}
final int sz = searchStrs.length;
// String's can't have a MAX_VALUEth index.
int ret = Integer.MAX_VALUE;
@ -2514,7 +2585,6 @@ public class StringUtils {
if (str == null || searchStrs == null) {
return INDEX_NOT_FOUND;
}
final int sz = searchStrs.length;
int ret = INDEX_NOT_FOUND;
int tmp = 0;
for (final CharSequence search : searchStrs) {
@ -7089,7 +7159,7 @@ public class StringUtils {
/**
* <p>Checks if the CharSequence contains only whitespace.</p>
*
* </p>Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
* <p>Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
*
* <p>{@code null} will return {@code false}.
* An empty CharSequence (length()=0) will return {@code true}.</p>
@ -7238,7 +7308,7 @@ public class StringUtils {
* <p>Returns either the passed in CharSequence, or if the CharSequence is
* whitespace, empty ("") or {@code null}, the value of {@code defaultStr}.</p>
*
* </p>Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
* <p>Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
*
* <pre>
* StringUtils.defaultIfBlank(null, "NULL") = "NULL"

View File

@ -18,7 +18,7 @@ package org.apache.commons.lang3.concurrent;
/**
* <p>Definition of an interface for a wrapper around a calculation that takes a single parameter and returns a result.</p>
* <p/>
*
* <p>This interface allows for wrapping a calculation into a class so that it maybe passed around an application.</p>
*
* @param <I> the type of the input to the calculation

View File

@ -0,0 +1,22 @@
/*
* 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.
*/
/**
* <p>Provides annotations to document classes' thread safety</p>
*
* @since 3.6
*/
package org.apache.commons.lang3.concurrent.annotation;

View File

@ -29,7 +29,6 @@ import java.util.StringTokenizer;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.ClassUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.SystemUtils;
/**
* <p>Provides utilities for manipulating and examining

View File

@ -675,9 +675,9 @@ public class DateUtils {
* @throws NullPointerException if {@code date} or {@code tz} is null
*/
public static Calendar toCalendar(final Date date, final TimeZone tz) {
final Calendar c = Calendar.getInstance(tz);
c.setTime(date);
return c;
final Calendar c = Calendar.getInstance(tz);
c.setTime(date);
return c;
}
//-----------------------------------------------------------------------

View File

@ -16,7 +16,6 @@
*/
package org.apache.commons.lang3;
import static org.apache.commons.lang3.JavaVersion.JAVA_1_5;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@ -378,21 +377,18 @@ public class ClassUtilsTest {
assertFalse(ClassUtils.isAssignable(null, array2));
assertTrue(ClassUtils.isAssignable(null, array0));
assertTrue(ClassUtils.isAssignable(array0, array0));
// assertTrue(ClassUtils.isAssignable(array0, null));
assertTrue(ClassUtils.isAssignable(array0, (Class<?>[]) null)); // explicit cast to avoid warning
assertTrue(ClassUtils.isAssignable((Class[]) null, null));
assertTrue(ClassUtils.isAssignable((Class[]) null, (Class<?>[]) null)); // explicit cast to avoid warning
assertFalse(ClassUtils.isAssignable(array1, array1s));
assertTrue(ClassUtils.isAssignable(array1s, array1s));
assertTrue(ClassUtils.isAssignable(array1s, array1));
final boolean autoboxing = SystemUtils.isJavaVersionAtLeast(JAVA_1_5);
assertEquals(autoboxing, ClassUtils.isAssignable(arrayPrimitives, arrayWrappers));
assertEquals(autoboxing, ClassUtils.isAssignable(arrayWrappers, arrayPrimitives));
assertTrue(ClassUtils.isAssignable(arrayPrimitives, arrayWrappers));
assertTrue(ClassUtils.isAssignable(arrayWrappers, arrayPrimitives));
assertFalse(ClassUtils.isAssignable(arrayPrimitives, array1));
assertFalse(ClassUtils.isAssignable(arrayWrappers, array1));
assertEquals(autoboxing, ClassUtils.isAssignable(arrayPrimitives, array2));
assertTrue(ClassUtils.isAssignable(arrayPrimitives, array2));
assertTrue(ClassUtils.isAssignable(arrayWrappers, array2));
}
@ -464,18 +460,16 @@ public class ClassUtilsTest {
assertTrue(ClassUtils.isAssignable(String.class, String.class));
assertFalse(ClassUtils.isAssignable(Object.class, String.class));
final boolean autoboxing = SystemUtils.isJavaVersionAtLeast(JAVA_1_5);
assertEquals(autoboxing, ClassUtils.isAssignable(Integer.TYPE, Integer.class));
assertEquals(autoboxing, ClassUtils.isAssignable(Integer.TYPE, Object.class));
assertEquals(autoboxing, ClassUtils.isAssignable(Integer.class, Integer.TYPE));
assertEquals(autoboxing, ClassUtils.isAssignable(Integer.class, Object.class));
assertTrue(ClassUtils.isAssignable(Integer.TYPE, Integer.class));
assertTrue(ClassUtils.isAssignable(Integer.TYPE, Object.class));
assertTrue(ClassUtils.isAssignable(Integer.class, Integer.TYPE));
assertTrue(ClassUtils.isAssignable(Integer.class, Object.class));
assertTrue(ClassUtils.isAssignable(Integer.TYPE, Integer.TYPE));
assertTrue(ClassUtils.isAssignable(Integer.class, Integer.class));
assertEquals(autoboxing, ClassUtils.isAssignable(Boolean.TYPE, Boolean.class));
assertEquals(autoboxing, ClassUtils.isAssignable(Boolean.TYPE, Object.class));
assertEquals(autoboxing, ClassUtils.isAssignable(Boolean.class, Boolean.TYPE));
assertEquals(autoboxing, ClassUtils.isAssignable(Boolean.class, Object.class));
assertTrue(ClassUtils.isAssignable(Boolean.TYPE, Boolean.class));
assertTrue(ClassUtils.isAssignable(Boolean.TYPE, Object.class));
assertTrue(ClassUtils.isAssignable(Boolean.class, Boolean.TYPE));
assertTrue(ClassUtils.isAssignable(Boolean.class, Object.class));
assertTrue(ClassUtils.isAssignable(Boolean.TYPE, Boolean.TYPE));
assertTrue(ClassUtils.isAssignable(Boolean.class, Boolean.class));
}
@ -613,46 +607,44 @@ public class ClassUtilsTest {
@Test
public void test_isAssignable_DefaultUnboxing_Widening() throws Exception {
final boolean autoboxing = SystemUtils.isJavaVersionAtLeast(JAVA_1_5);
// test byte conversions
assertFalse("byte -> char", ClassUtils.isAssignable(Byte.class, Character.TYPE));
assertEquals("byte -> byte", autoboxing, ClassUtils.isAssignable(Byte.class, Byte.TYPE));
assertEquals("byte -> short", autoboxing, ClassUtils.isAssignable(Byte.class, Short.TYPE));
assertEquals("byte -> int", autoboxing, ClassUtils.isAssignable(Byte.class, Integer.TYPE));
assertEquals("byte -> long", autoboxing, ClassUtils.isAssignable(Byte.class, Long.TYPE));
assertEquals("byte -> float", autoboxing, ClassUtils.isAssignable(Byte.class, Float.TYPE));
assertEquals("byte -> double", autoboxing, ClassUtils.isAssignable(Byte.class, Double.TYPE));
assertTrue("byte -> byte", ClassUtils.isAssignable(Byte.class, Byte.TYPE));
assertTrue("byte -> short", ClassUtils.isAssignable(Byte.class, Short.TYPE));
assertTrue("byte -> int", ClassUtils.isAssignable(Byte.class, Integer.TYPE));
assertTrue("byte -> long", ClassUtils.isAssignable(Byte.class, Long.TYPE));
assertTrue("byte -> float", ClassUtils.isAssignable(Byte.class, Float.TYPE));
assertTrue("byte -> double", ClassUtils.isAssignable(Byte.class, Double.TYPE));
assertFalse("byte -> boolean", ClassUtils.isAssignable(Byte.class, Boolean.TYPE));
// test short conversions
assertFalse("short -> char", ClassUtils.isAssignable(Short.class, Character.TYPE));
assertFalse("short -> byte", ClassUtils.isAssignable(Short.class, Byte.TYPE));
assertEquals("short -> short", autoboxing, ClassUtils.isAssignable(Short.class, Short.TYPE));
assertEquals("short -> int", autoboxing, ClassUtils.isAssignable(Short.class, Integer.TYPE));
assertEquals("short -> long", autoboxing, ClassUtils.isAssignable(Short.class, Long.TYPE));
assertEquals("short -> float", autoboxing, ClassUtils.isAssignable(Short.class, Float.TYPE));
assertEquals("short -> double", autoboxing, ClassUtils.isAssignable(Short.class, Double.TYPE));
assertTrue("short -> short", ClassUtils.isAssignable(Short.class, Short.TYPE));
assertTrue("short -> int", ClassUtils.isAssignable(Short.class, Integer.TYPE));
assertTrue("short -> long", ClassUtils.isAssignable(Short.class, Long.TYPE));
assertTrue("short -> float", ClassUtils.isAssignable(Short.class, Float.TYPE));
assertTrue("short -> double", ClassUtils.isAssignable(Short.class, Double.TYPE));
assertFalse("short -> boolean", ClassUtils.isAssignable(Short.class, Boolean.TYPE));
// test char conversions
assertEquals("char -> char", autoboxing, ClassUtils.isAssignable(Character.class, Character.TYPE));
assertTrue("char -> char", ClassUtils.isAssignable(Character.class, Character.TYPE));
assertFalse("char -> byte", ClassUtils.isAssignable(Character.class, Byte.TYPE));
assertFalse("char -> short", ClassUtils.isAssignable(Character.class, Short.TYPE));
assertEquals("char -> int", autoboxing, ClassUtils.isAssignable(Character.class, Integer.TYPE));
assertEquals("char -> long", autoboxing, ClassUtils.isAssignable(Character.class, Long.TYPE));
assertEquals("char -> float", autoboxing, ClassUtils.isAssignable(Character.class, Float.TYPE));
assertEquals("char -> double", autoboxing, ClassUtils.isAssignable(Character.class, Double.TYPE));
assertTrue("char -> int", ClassUtils.isAssignable(Character.class, Integer.TYPE));
assertTrue("char -> long", ClassUtils.isAssignable(Character.class, Long.TYPE));
assertTrue("char -> float", ClassUtils.isAssignable(Character.class, Float.TYPE));
assertTrue("char -> double", ClassUtils.isAssignable(Character.class, Double.TYPE));
assertFalse("char -> boolean", ClassUtils.isAssignable(Character.class, Boolean.TYPE));
// test int conversions
assertFalse("int -> char", ClassUtils.isAssignable(Integer.class, Character.TYPE));
assertFalse("int -> byte", ClassUtils.isAssignable(Integer.class, Byte.TYPE));
assertFalse("int -> short", ClassUtils.isAssignable(Integer.class, Short.TYPE));
assertEquals("int -> int", autoboxing, ClassUtils.isAssignable(Integer.class, Integer.TYPE));
assertEquals("int -> long", autoboxing, ClassUtils.isAssignable(Integer.class, Long.TYPE));
assertEquals("int -> float", autoboxing, ClassUtils.isAssignable(Integer.class, Float.TYPE));
assertEquals("int -> double", autoboxing, ClassUtils.isAssignable(Integer.class, Double.TYPE));
assertTrue("int -> int", ClassUtils.isAssignable(Integer.class, Integer.TYPE));
assertTrue("int -> long", ClassUtils.isAssignable(Integer.class, Long.TYPE));
assertTrue("int -> float", ClassUtils.isAssignable(Integer.class, Float.TYPE));
assertTrue("int -> double", ClassUtils.isAssignable(Integer.class, Double.TYPE));
assertFalse("int -> boolean", ClassUtils.isAssignable(Integer.class, Boolean.TYPE));
// test long conversions
@ -660,9 +652,9 @@ public class ClassUtilsTest {
assertFalse("long -> byte", ClassUtils.isAssignable(Long.class, Byte.TYPE));
assertFalse("long -> short", ClassUtils.isAssignable(Long.class, Short.TYPE));
assertFalse("long -> int", ClassUtils.isAssignable(Long.class, Integer.TYPE));
assertEquals("long -> long", autoboxing, ClassUtils.isAssignable(Long.class, Long.TYPE));
assertEquals("long -> float", autoboxing, ClassUtils.isAssignable(Long.class, Float.TYPE));
assertEquals("long -> double", autoboxing, ClassUtils.isAssignable(Long.class, Double.TYPE));
assertTrue("long -> long", ClassUtils.isAssignable(Long.class, Long.TYPE));
assertTrue("long -> float", ClassUtils.isAssignable(Long.class, Float.TYPE));
assertTrue("long -> double", ClassUtils.isAssignable(Long.class, Double.TYPE));
assertFalse("long -> boolean", ClassUtils.isAssignable(Long.class, Boolean.TYPE));
// test float conversions
@ -671,8 +663,8 @@ public class ClassUtilsTest {
assertFalse("float -> short", ClassUtils.isAssignable(Float.class, Short.TYPE));
assertFalse("float -> int", ClassUtils.isAssignable(Float.class, Integer.TYPE));
assertFalse("float -> long", ClassUtils.isAssignable(Float.class, Long.TYPE));
assertEquals("float -> float", autoboxing, ClassUtils.isAssignable(Float.class, Float.TYPE));
assertEquals("float -> double", autoboxing, ClassUtils.isAssignable(Float.class, Double.TYPE));
assertTrue("float -> float", ClassUtils.isAssignable(Float.class, Float.TYPE));
assertTrue("float -> double", ClassUtils.isAssignable(Float.class, Double.TYPE));
assertFalse("float -> boolean", ClassUtils.isAssignable(Float.class, Boolean.TYPE));
// test double conversions
@ -682,7 +674,7 @@ public class ClassUtilsTest {
assertFalse("double -> int", ClassUtils.isAssignable(Double.class, Integer.TYPE));
assertFalse("double -> long", ClassUtils.isAssignable(Double.class, Long.TYPE));
assertFalse("double -> float", ClassUtils.isAssignable(Double.class, Float.TYPE));
assertEquals("double -> double", autoboxing, ClassUtils.isAssignable(Double.class, Double.TYPE));
assertTrue("double -> double", ClassUtils.isAssignable(Double.class, Double.TYPE));
assertFalse("double -> boolean", ClassUtils.isAssignable(Double.class, Boolean.TYPE));
// test boolean conversions
@ -693,7 +685,7 @@ public class ClassUtilsTest {
assertFalse("boolean -> long", ClassUtils.isAssignable(Boolean.class, Long.TYPE));
assertFalse("boolean -> float", ClassUtils.isAssignable(Boolean.class, Float.TYPE));
assertFalse("boolean -> double", ClassUtils.isAssignable(Boolean.class, Double.TYPE));
assertEquals("boolean -> boolean", autoboxing, ClassUtils.isAssignable(Boolean.class, Boolean.TYPE));
assertTrue("boolean -> boolean", ClassUtils.isAssignable(Boolean.class, Boolean.TYPE));
}
@Test

View File

@ -56,19 +56,6 @@ public class StringUtilsEmptyBlankTest {
assertFalse(StringUtils.isAnyEmpty("foo", "bar"));
}
@Test
public void testIsAnyNotEmpty() {
assertFalse(StringUtils.isAnyNotEmpty((String) null));
assertFalse(StringUtils.isAnyNotEmpty((String[]) null));
assertTrue(StringUtils.isAnyNotEmpty(null, "foo"));
assertTrue(StringUtils.isAnyNotEmpty("", "bar"));
assertTrue(StringUtils.isAnyNotEmpty("bob", ""));
assertTrue(StringUtils.isAnyNotEmpty(" bob ", null));
assertTrue(StringUtils.isAnyNotEmpty(" ", "bar"));
assertTrue(StringUtils.isAnyNotEmpty("foo", "bar"));
assertFalse(StringUtils.isAnyNotEmpty("", null));
}
@Test
public void testIsNoneEmpty() {
assertFalse(StringUtils.isNoneEmpty((String) null));
@ -81,6 +68,21 @@ public class StringUtilsEmptyBlankTest {
assertTrue(StringUtils.isNoneEmpty("foo", "bar"));
}
@Test
public void testIsAllEmpty() {
assertTrue(StringUtils.isAllEmpty());
assertTrue(StringUtils.isAllEmpty(new String[]{}));
assertTrue(StringUtils.isAllEmpty((String) null));
assertTrue(StringUtils.isAllEmpty((String[]) null));
assertFalse(StringUtils.isAllEmpty(null, "foo"));
assertFalse(StringUtils.isAllEmpty("", "bar"));
assertFalse(StringUtils.isAllEmpty("bob", ""));
assertFalse(StringUtils.isAllEmpty(" bob ", null));
assertFalse(StringUtils.isAllEmpty(" ", "bar"));
assertFalse(StringUtils.isAllEmpty("foo", "bar"));
assertTrue(StringUtils.isAllEmpty("", null));
}
@Test
public void testIsBlank() {
assertTrue(StringUtils.isBlank(null));
@ -112,19 +114,6 @@ public class StringUtilsEmptyBlankTest {
assertFalse(StringUtils.isAnyBlank("foo", "bar"));
}
@Test
public void testIsAnyNotBlank() {
assertFalse(StringUtils.isAnyNotBlank((String) null));
assertFalse(StringUtils.isAnyNotBlank((String[]) null));
assertTrue(StringUtils.isAnyNotBlank(null, "foo"));
assertFalse(StringUtils.isAnyNotBlank(null, null));
assertTrue(StringUtils.isAnyNotBlank("", "bar"));
assertTrue(StringUtils.isAnyNotBlank("bob", ""));
assertTrue(StringUtils.isAnyNotBlank(" bob ", null));
assertTrue(StringUtils.isAnyNotBlank(" ", "bar"));
assertTrue(StringUtils.isAnyNotBlank("foo", "bar"));
}
@Test
public void testIsNoneBlank() {
assertFalse(StringUtils.isNoneBlank((String) null));
@ -137,4 +126,18 @@ public class StringUtilsEmptyBlankTest {
assertFalse(StringUtils.isNoneBlank(" ", "bar"));
assertTrue(StringUtils.isNoneBlank("foo", "bar"));
}
@Test
public void testIsAllBlank() {
assertTrue(StringUtils.isAllBlank((String) null));
assertTrue(StringUtils.isAllBlank((String[]) null));
assertTrue(StringUtils.isAllBlank(null, null));
assertTrue(StringUtils.isAllBlank(null, " "));
assertFalse(StringUtils.isAllBlank(null, "foo"));
assertFalse(StringUtils.isAllBlank("", "bar"));
assertFalse(StringUtils.isAllBlank("bob", ""));
assertFalse(StringUtils.isAllBlank(" bob ", null));
assertFalse(StringUtils.isAllBlank(" ", "bar"));
assertFalse(StringUtils.isAllBlank("foo", "bar"));
}
}

View File

@ -294,6 +294,28 @@ public class StringUtilsEqualsIndexOfTest {
assertEquals(2, StringUtils.indexOf("aabaabaa", 'b', -1));
assertEquals(5, StringUtils.indexOf(new StringBuilder("aabaabaa"), 'b', 3));
//LANG-1300 tests go here
final int CODE_POINT = 0x2070E;
StringBuilder builder = new StringBuilder();
builder.appendCodePoint(CODE_POINT);
assertEquals(0, StringUtils.indexOf(builder, CODE_POINT, 0));
assertEquals(0, StringUtils.indexOf(builder.toString(), CODE_POINT, 0));
builder.appendCodePoint(CODE_POINT);
assertEquals(2, StringUtils.indexOf(builder, CODE_POINT, 1));
assertEquals(2, StringUtils.indexOf(builder.toString(), CODE_POINT, 1));
//inner branch on the supplementary character block
char[] tmp = {(char) 55361};
builder = new StringBuilder();
builder.append(tmp);
assertEquals(-1, StringUtils.indexOf(builder, CODE_POINT, 0));
assertEquals(-1, StringUtils.indexOf(builder.toString(), CODE_POINT, 0));
builder.appendCodePoint(CODE_POINT);
assertEquals(1, StringUtils.indexOf(builder, CODE_POINT, 0));
assertEquals(1, StringUtils.indexOf(builder.toString(), CODE_POINT, 0));
assertEquals(-1, StringUtils.indexOf(builder, CODE_POINT, 2));
assertEquals(-1, StringUtils.indexOf(builder.toString(), CODE_POINT, 2));
}
@Test
@ -525,6 +547,33 @@ public class StringUtilsEqualsIndexOfTest {
assertEquals(0, StringUtils.lastIndexOf("aabaabaa", 'a', 0));
assertEquals(2, StringUtils.lastIndexOf(new StringBuilder("aabaabaa"), 'b', 2));
//LANG-1300 addition test
final int CODE_POINT = 0x2070E;
StringBuilder builder = new StringBuilder();
builder.appendCodePoint(CODE_POINT);
assertEquals(0, StringUtils.lastIndexOf(builder, CODE_POINT, 0));
builder.appendCodePoint(CODE_POINT);
assertEquals(0, StringUtils.lastIndexOf(builder, CODE_POINT, 0));
assertEquals(0, StringUtils.lastIndexOf(builder, CODE_POINT, 1));
assertEquals(2, StringUtils.lastIndexOf(builder, CODE_POINT, 2));
builder.append("aaaaa");
assertEquals(2, StringUtils.lastIndexOf(builder, CODE_POINT, 4));
//inner branch on the supplementary character block
char[] tmp = {(char) 55361};
builder = new StringBuilder();
builder.append(tmp);
assertEquals(-1, StringUtils.lastIndexOf(builder, CODE_POINT, 0));
builder.appendCodePoint(CODE_POINT);
assertEquals(-1, StringUtils.lastIndexOf(builder, CODE_POINT, 0 ));
assertEquals(1, StringUtils.lastIndexOf(builder, CODE_POINT, 1 ));
assertEquals(-1, StringUtils.lastIndexOf(builder.toString(), CODE_POINT, 0));
assertEquals(1, StringUtils.lastIndexOf(builder.toString(), CODE_POINT, 1));
}
@Test

View File

@ -180,8 +180,8 @@ public abstract class AbstractExceptionContextTest<T extends ExceptionContext &
public void testJavaSerialization() {
exceptionContext.setContextValue("test Poorly written obj", "serializable replacement");
@SuppressWarnings("unchecked")
final T clone = SerializationUtils.deserialize(SerializationUtils.serialize(exceptionContext));
assertEquals(exceptionContext.getFormattedExceptionMessage(null), clone.getFormattedExceptionMessage(null));
}
}