/* * 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.eclipse.leshan.util; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; /** * <p> * Operations on {@link java.lang.String} that are <code>null</code> safe. * </p> * * <ul> * <li><b>IsEmpty/IsBlank</b> - checks if a String contains text</li> * <li><b>Trim/Strip</b> - removes leading and trailing whitespace</li> * <li><b>Equals</b> - compares two strings null-safe</li> * <li><b>startsWith</b> - check if a String starts with a prefix null-safe</li> * <li><b>endsWith</b> - check if a String ends with a suffix null-safe</li> * <li><b>IndexOf/LastIndexOf/Contains</b> - null-safe index-of checks * <li><b>IndexOfAny/LastIndexOfAny/IndexOfAnyBut/LastIndexOfAnyBut</b> - index-of any of a set of Strings</li> * <li><b>ContainsOnly/ContainsNone/ContainsAny</b> - does String contains only/none/any of these characters</li> * <li><b>Substring/Left/Right/Mid</b> - null-safe substring extractions</li> * <li><b>SubstringBefore/SubstringAfter/SubstringBetween</b> - substring extraction relative to other strings</li> * <li><b>Split/Join</b> - splits a String into an array of substrings and vice versa</li> * <li><b>Remove/Delete</b> - removes part of a String</li> * <li><b>Replace/Overlay</b> - Searches a String and replaces one String with another</li> * <li><b>Chomp/Chop</b> - removes the last part of a String</li> * <li><b>LeftPad/RightPad/Center/Repeat</b> - pads a String</li> * <li><b>UpperCase/LowerCase/SwapCase/Capitalize/Uncapitalize</b> - changes the case of a String</li> * <li><b>CountMatches</b> - counts the number of occurrences of one String in another</li> * <li><b>IsAlpha/IsNumeric/IsWhitespace/IsAsciiPrintable</b> - checks the characters in a String</li> * <li><b>DefaultString</b> - protects against a null input String</li> * <li><b>Reverse/ReverseDelimited</b> - reverses a String</li> * <li><b>Abbreviate</b> - abbreviates a string using ellipsis</li> * <li><b>Difference</b> - compares Strings and reports on their differences</li> * <li><b>LevensteinDistance</b> - the number of changes needed to change one String into another</li> * </ul> * * <p> * The <code>StringUtils</code> class defines certain words related to String handling. * </p> * * <ul> * <li>null - <code>null</code></li> * <li>empty - a zero-length string (<code>""</code>)</li> * <li>space - the space character (<code>' '</code>, char 32)</li> * <li>whitespace - the characters defined by {@link Character#isWhitespace(char)}</li> * <li>trim - the characters <= 32 as in {@link String#trim()}</li> * </ul> * * <p> * <code>StringUtils</code> handles <code>null</code> input Strings quietly. That is to say that a <code>null</code> * input will return <code>null</code>. Where a <code>boolean</code> or <code>int</code> is being returned details vary * by method. * </p> * * <p> * A side effect of the <code>null</code> handling is that a <code>NullPointerException</code> should be considered a * bug in <code>StringUtils</code> (except for deprecated methods). * </p> * * <p> * Methods in this class give sample code to explain their operation. The symbol <code>*</code> is used to indicate any * input including <code>null</code>. * </p> * * <p> * #ThreadSafe# * </p> * * @see java.lang.String * @author Apache Software Foundation * @author <a href="http://jakarta.apache.org/turbine/">Apache Jakarta Turbine</a> * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a> * @author Daniel L. Rall * @author <a href="mailto:gcoladonato@yahoo.com">Greg Coladonato</a> * @author <a href="mailto:ed@apache.org">Ed Korthof</a> * @author <a href="mailto:rand_mcneely@yahoo.com">Rand McNeely</a> * @author <a href="mailto:fredrik@westermarck.com">Fredrik Westermarck</a> * @author Holger Krauth * @author <a href="mailto:alex@purpletech.com">Alexander Day Chaffee</a> * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a> * @author Arun Mammen Thomas * @author Gary Gregory * @author Phil Steitz * @author Al Chou * @author Michael Davey * @author Reuben Sivan * @author Chris Hyzer * @author Scott Johnson * @since 1.0 * @version $Id: StringUtils.java 1058365 2011-01-13 00:04:49Z niallp $ */ // @Immutable public class StringUtils { // Equals // ----------------------------------------------------------------------- /** * <p> * Compares two Strings, returning <code>true</code> if they are equal. * </p> * * <p> * <code>null</code>s are handled without exceptions. Two <code>null</code> references are considered to be equal. * The comparison is case sensitive. * </p> * * <pre> * 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 * </pre> * * @see java.lang.String#equals(Object) * @param str1 the first String, may be null * @param str2 the second String, may be null * @return <code>true</code> if the Strings are equal, case sensitive, or both <code>null</code> */ public static boolean equals(String str1, String str2) { return str1 == null ? str2 == null : str1.equals(str2); } /** * <p> * Compares two Strings, returning <code>true</code> if they are equal ignoring the case. * </p> * * <p> * <code>null</code>s are handled without exceptions. Two <code>null</code> references are considered equal. * Comparison is case insensitive. * </p> * * <pre> * StringUtils.equalsIgnoreCase(null, null) = true * StringUtils.equalsIgnoreCase(null, "abc") = false * StringUtils.equalsIgnoreCase("abc", null) = false * StringUtils.equalsIgnoreCase("abc", "abc") = true * StringUtils.equalsIgnoreCase("abc", "ABC") = true * </pre> * * @see java.lang.String#equalsIgnoreCase(String) * @param str1 the first String, may be null * @param str2 the second String, may be null * @return <code>true</code> if the Strings are equal, case insensitive, or both <code>null</code> */ public static boolean equalsIgnoreCase(String str1, String str2) { return str1 == null ? str2 == null : str1.equalsIgnoreCase(str2); } // Empty checks // ----------------------------------------------------------------------- /** * <p> * Checks if a String is empty ("") or null. * </p> * * <pre> * StringUtils.isEmpty(null) = true * StringUtils.isEmpty("") = true * StringUtils.isEmpty(" ") = false * StringUtils.isEmpty("bob") = false * StringUtils.isEmpty(" bob ") = false * </pre> * * <p> * NOTE: This method changed in Lang version 2.0. It no longer trims the String. That functionality is available in * isBlank(). * </p> * * @param str the String to check, may be null * @return <code>true</code> if the String is empty or null */ public static boolean isEmpty(String str) { return str == null || str.length() == 0; } // Trim // ----------------------------------------------------------------------- /** * <p> * Removes control characters (char <= 32) from both ends of this String, handling <code>null</code> by returning * <code>null</code>. * </p> * * <p> * The String is trimmed using {@link String#trim()}. Trim removes start and end characters <= 32. To strip * whitespace use {@link #strip(String)}. * </p> * * <p> * To trim your choice of characters, use the {@link #strip(String, String)} methods. * </p> * * <pre> * StringUtils.trim(null) = null * StringUtils.trim("") = "" * StringUtils.trim(" ") = "" * StringUtils.trim("abc") = "abc" * StringUtils.trim(" abc ") = "abc" * </pre> * * @param str the String to be trimmed, may be null * @return the trimmed string, <code>null</code> if null String input */ public static String trim(String str) { return str == null ? null : str.trim(); } // Remove // ----------------------------------------------------------------------- /** * <p> * Removes a substring only if it is at the beginning of a source string, otherwise returns the source string. * </p> * * <p> * A <code>null</code> source string will return <code>null</code>. An empty ("") source string will return the * empty string. A <code>null</code> search string will return the source string. * </p> * * <pre> * 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" * </pre> * * @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</code> 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; } /** * <p> * Removes a substring only if it is at the end of a source string, otherwise returns the source string. * </p> * * <p> * A <code>null</code> source string will return <code>null</code>. An empty ("") source string will return the * empty string. A <code>null</code> search string will return the source string. * </p> * * <pre> * 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" * </pre> * * @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</code> 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; } /** * Constructs a new <code>String</code> by decoding the specified array of bytes using the given charset. * * @param bytes The bytes to be decoded into characters * @param charset The {@link Charset} to encode the <code>String</code> * @return A new <code>String</code> decoded from the specified array of bytes using the given charset, or * <code>null</code> if the input byte array was <code>null</code>. * @throws NullPointerException Thrown if {@link StandardCharsets#UTF_8} is not initialized, which should never happen since * it is required by the Java platform specification. */ private static String newString(final byte[] bytes, final Charset charset) { return bytes == null ? null : new String(bytes, charset); } /** * Constructs a new <code>String</code> by decoding the specified array of bytes using the UTF-8 charset. * * @param bytes The bytes to be decoded into characters * @return A new <code>String</code> decoded from the specified array of bytes using the UTF-8 charset, or * <code>null</code> if the input byte array was <code>null</code>. * @throws NullPointerException Thrown if {@link StandardCharsets#UTF_8} is not initialized, which should never happen since * it is required by the Java platform specification. * @since As of 1.7, throws {@link NullPointerException} instead of UnsupportedEncodingException */ public static String newStringUtf8(final byte[] bytes) { return newString(bytes, StandardCharsets.UTF_8); } /** * Calls {@link String#getBytes(Charset)} * * @param string The string to encode (if null, return null). * @param charset The {@link Charset} to encode the <code>String</code> * @return the encoded bytes */ private static byte[] getBytes(final String string, final Charset charset) { if (string == null) { return null; } return string.getBytes(charset); } /** * Encodes the given string into a sequence of bytes using the UTF-8 charset, storing the result into a new byte * array. * * @param string the String to encode, may be <code>null</code> * @return encoded bytes, or <code>null</code> if the input string was <code>null</code> * @throws NullPointerException Thrown if {@link StandardCharsets#UTF_8} is not initialized, which should never happen since * it is required by the Java platform specification. * @since As of 1.7, throws {@link NullPointerException} instead of UnsupportedEncodingException * @see <a href="http://download.oracle.com/javase/6/docs/api/java/nio/charset/Charset.html">Standard charsets</a> * @see #getBytesUnchecked(String, String) */ public static byte[] getBytesUtf8(final String string) { return getBytes(string, StandardCharsets.UTF_8); } }