    001    /*
    002     * Licensed to the Apache Software Foundation (ASF) under one or more
    003     * contributor license agreements.  See the NOTICE file distributed with
    004     * this work for additional information regarding copyright ownership.
    005     * The ASF licenses this file to You under the Apache License, Version 2.0
    006     * (the "License"); you may not use this file except in compliance with
    007     * the License.  You may obtain a copy of the License at
    008     *
    009     *      http://www.apache.org/licenses/LICENSE-2.0
    010     *
    011     * Unless required by applicable law or agreed to in writing, software
    012     * distributed under the License is distributed on an "AS IS" BASIS,
    013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014     * See the License for the specific language governing permissions and
    015     * limitations under the License.
    016     */
    017    package org.apache.commons.lang3;
    018
    019    /**
    020     * <p>Operations on char primitives and Character objects.</p>
    021     *
    022     * <p>This class tries to handle {@code null} input gracefully.
    023     * An exception will not be thrown for a {@code null} input.
    024     * Each method documents its behaviour in more detail.</p>
    025     *
    026     * <p>#ThreadSafe#</p>
    027     * @since 2.1
    028     * @version $Id: CharUtils.java 1158279 2011-08-16 14:06:45Z ggregory $
    029     */
    030    public class CharUtils {
    031
    032        private static final String[] CHAR_STRING_ARRAY = new String[128];
    033
    034        /**
    035         * {@code \u000a} linefeed LF ('\n').
    036         *
    037         * @see <a href="http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#101089">JLF: Escape Sequences
    038         *      for Character and String Literals</a>
    039         * @since 2.2
    040         */
    041        public static final char LF = '\n';
    042
    043        /**
    044         * {@code \u000d} carriage return CR ('\r').
    045         *
    046         * @see <a href="http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#101089">JLF: Escape Sequences
    047         *      for Character and String Literals</a>
    048         * @since 2.2
    049         */
    050        public static final char CR = '\r';
    051
    052
    053        static {
    054            for (char c = 0; c < CHAR_STRING_ARRAY.length; c++) {
    055                CHAR_STRING_ARRAY[c] = String.valueOf(c);
    056            }
    057        }
    058
    059        /**
    060         * <p>{@code CharUtils} instances should NOT be constructed in standard programming.
    061         * Instead, the class should be used as {@code CharUtils.toString('c');}.</p>
    062         *
    063         * <p>This constructor is public to permit tools that require a JavaBean instance
    064         * to operate.</p>
    065         */
    066        public CharUtils() {
    067          super();
    068        }
    069
    070        //-----------------------------------------------------------------------
    071        /**
    072         * <p>Converts the character to a Character.</p>
    073         *
    074         * <p>For ASCII 7 bit characters, this uses a cache that will return the
    075         * same Character object each time.</p>
    076         *
    077         * <pre>
    078         *   CharUtils.toCharacterObject(' ')  = ' '
    079         *   CharUtils.toCharacterObject('A')  = 'A'
    080         * </pre>
    081         *
    082         * @deprecated Java 5 introduced {@link Character#valueOf(char)} which caches chars 0 through 127.
    083         * @param ch  the character to convert
    084         * @return a Character of the specified character
    085         */
    086        @Deprecated
    087        public static Character toCharacterObject(char ch) {
    088            return Character.valueOf(ch);
    089        }
    090
    091        /**
    092         * <p>Converts the String to a Character using the first character, returning
    093         * null for empty Strings.</p>
    094         *
    095         * <p>For ASCII 7 bit characters, this uses a cache that will return the
    096         * same Character object each time.</p>
    097         *
    098         * <pre>
    099         *   CharUtils.toCharacterObject(null) = null
    100         *   CharUtils.toCharacterObject("")   = null
    101         *   CharUtils.toCharacterObject("A")  = 'A'
    102         *   CharUtils.toCharacterObject("BA") = 'B'
    103         * </pre>
    104         *
    105         * @param str  the character to convert
    106         * @return the Character value of the first letter of the String
    107         */
    108        public static Character toCharacterObject(String str) {
    109            if (StringUtils.isEmpty(str)) {
    110                return null;
    111            }
    112            return Character.valueOf(str.charAt(0));
    113        }
    114
    115        //-----------------------------------------------------------------------
    116        /**
    117         * <p>Converts the Character to a char throwing an exception for {@code null}.</p>
    118         *
    119         * <pre>
    120         *   CharUtils.toChar(' ')  = ' '
    121         *   CharUtils.toChar('A')  = 'A'
    122         *   CharUtils.toChar(null) throws IllegalArgumentException
    123         * </pre>
    124         *
    125         * @param ch  the character to convert
    126         * @return the char value of the Character
    127         * @throws IllegalArgumentException if the Character is null
    128         */
    129        public static char toChar(Character ch) {
    130            if (ch == null) {
    131                throw new IllegalArgumentException("The Character must not be null");
    132            }
    133            return ch.charValue();
    134        }
    135
    136        /**
    137         * <p>Converts the Character to a char handling {@code null}.</p>
    138         *
    139         * <pre>
    140         *   CharUtils.toChar(null, 'X') = 'X'
    141         *   CharUtils.toChar(' ', 'X')  = ' '
    142         *   CharUtils.toChar('A', 'X')  = 'A'
    143         * </pre>
    144         *
    145         * @param ch  the character to convert
    146         * @param defaultValue  the value to use if the  Character is null
    147         * @return the char value of the Character or the default if null
    148         */
    149        public static char toChar(Character ch, char defaultValue) {
    150            if (ch == null) {
    151                return defaultValue;
    152            }
    153            return ch.charValue();
    154        }
    155
    156        //-----------------------------------------------------------------------
    157        /**
    158         * <p>Converts the String to a char using the first character, throwing
    159         * an exception on empty Strings.</p>
    160         *
    161         * <pre>
    162         *   CharUtils.toChar("A")  = 'A'
    163         *   CharUtils.toChar("BA") = 'B'
    164         *   CharUtils.toChar(null) throws IllegalArgumentException
    165         *   CharUtils.toChar("")   throws IllegalArgumentException
    166         * </pre>
    167         *
    168         * @param str  the character to convert
    169         * @return the char value of the first letter of the String
    170         * @throws IllegalArgumentException if the String is empty
    171         */
    172        public static char toChar(String str) {
    173            if (StringUtils.isEmpty(str)) {
    174                throw new IllegalArgumentException("The String must not be empty");
    175            }
    176            return str.charAt(0);
    177        }
    178
    179        /**
    180         * <p>Converts the String to a char using the first character, defaulting
    181         * the value on empty Strings.</p>
    182         *
    183         * <pre>
    184         *   CharUtils.toChar(null, 'X') = 'X'
    185         *   CharUtils.toChar("", 'X')   = 'X'
    186         *   CharUtils.toChar("A", 'X')  = 'A'
    187         *   CharUtils.toChar("BA", 'X') = 'B'
    188         * </pre>
    189         *
    190         * @param str  the character to convert
    191         * @param defaultValue  the value to use if the  Character is null
    192         * @return the char value of the first letter of the String or the default if null
    193         */
    194        public static char toChar(String str, char defaultValue) {
    195            if (StringUtils.isEmpty(str)) {
    196                return defaultValue;
    197            }
    198            return str.charAt(0);
    199        }
    200
    201        //-----------------------------------------------------------------------
    202        /**
    203         * <p>Converts the character to the Integer it represents, throwing an
    204         * exception if the character is not numeric.</p>
    205         *
    206         * <p>This method coverts the char '1' to the int 1 and so on.</p>
    207         *
    208         * <pre>
    209         *   CharUtils.toIntValue('3')  = 3
    210         *   CharUtils.toIntValue('A')  throws IllegalArgumentException
    211         * </pre>
    212         *
    213         * @param ch  the character to convert
    214         * @return the int value of the character
    215         * @throws IllegalArgumentException if the character is not ASCII numeric
    216         */
    217        public static int toIntValue(char ch) {
    218            if (isAsciiNumeric(ch) == false) {
    219                throw new IllegalArgumentException("The character " + ch + " is not in the range '0' - '9'");
    220            }
    221            return ch - 48;
    222        }
    223
    224        /**
    225         * <p>Converts the character to the Integer it represents, throwing an
    226         * exception if the character is not numeric.</p>
    227         *
    228         * <p>This method coverts the char '1' to the int 1 and so on.</p>
    229         *
    230         * <pre>
    231         *   CharUtils.toIntValue('3', -1)  = 3
    232         *   CharUtils.toIntValue('A', -1)  = -1
    233         * </pre>
    234         *
    235         * @param ch  the character to convert
    236         * @param defaultValue  the default value to use if the character is not numeric
    237         * @return the int value of the character
    238         */
    239        public static int toIntValue(char ch, int defaultValue) {
    240            if (isAsciiNumeric(ch) == false) {
    241                return defaultValue;
    242            }
    243            return ch - 48;
    244        }
    245
    246        /**
    247         * <p>Converts the character to the Integer it represents, throwing an
    248         * exception if the character is not numeric.</p>
    249         *
    250         * <p>This method coverts the char '1' to the int 1 and so on.</p>
    251         *
    252         * <pre>
    253         *   CharUtils.toIntValue('3')  = 3
    254         *   CharUtils.toIntValue(null) throws IllegalArgumentException
    255         *   CharUtils.toIntValue('A')  throws IllegalArgumentException
    256         * </pre>
    257         *
    258         * @param ch  the character to convert, not null
    259         * @return the int value of the character
    260         * @throws IllegalArgumentException if the Character is not ASCII numeric or is null
    261         */
    262        public static int toIntValue(Character ch) {
    263            if (ch == null) {
    264                throw new IllegalArgumentException("The character must not be null");
    265            }
    266            return toIntValue(ch.charValue());
    267        }
    268
    269        /**
    270         * <p>Converts the character to the Integer it represents, throwing an
    271         * exception if the character is not numeric.</p>
    272         *
    273         * <p>This method coverts the char '1' to the int 1 and so on.</p>
    274         *
    275         * <pre>
    276         *   CharUtils.toIntValue(null, -1) = -1
    277         *   CharUtils.toIntValue('3', -1)  = 3
    278         *   CharUtils.toIntValue('A', -1)  = -1
    279         * </pre>
    280         *
    281         * @param ch  the character to convert
    282         * @param defaultValue  the default value to use if the character is not numeric
    283         * @return the int value of the character
    284         */
    285        public static int toIntValue(Character ch, int defaultValue) {
    286            if (ch == null) {
    287                return defaultValue;
    288            }
    289            return toIntValue(ch.charValue(), defaultValue);
    290        }
    291
    292        //-----------------------------------------------------------------------
    293        /**
    294         * <p>Converts the character to a String that contains the one character.</p>
    295         *
    296         * <p>For ASCII 7 bit characters, this uses a cache that will return the
    297         * same String object each time.</p>
    298         *
    299         * <pre>
    300         *   CharUtils.toString(' ')  = " "
    301         *   CharUtils.toString('A')  = "A"
    302         * </pre>
    303         *
    304         * @param ch  the character to convert
    305         * @return a String containing the one specified character
    306         */
    307        public static String toString(char ch) {
    308            if (ch < 128) {
    309                return CHAR_STRING_ARRAY[ch];
    310            }
    311            return new String(new char[] {ch});
    312        }
    313
    314        /**
    315         * <p>Converts the character to a String that contains the one character.</p>
    316         *
    317         * <p>For ASCII 7 bit characters, this uses a cache that will return the
    318         * same String object each time.</p>
    319         *
    320         * <p>If {@code null} is passed in, {@code null} will be returned.</p>
    321         *
    322         * <pre>
    323         *   CharUtils.toString(null) = null
    324         *   CharUtils.toString(' ')  = " "
    325         *   CharUtils.toString('A')  = "A"
    326         * </pre>
    327         *
    328         * @param ch  the character to convert
    329         * @return a String containing the one specified character
    330         */
    331        public static String toString(Character ch) {
    332            if (ch == null) {
    333                return null;
    334            }
    335            return toString(ch.charValue());
    336        }
    337
    338        //--------------------------------------------------------------------------
    339        /**
    340         * <p>Converts the string to the Unicode format '\u0020'.</p>
    341         *
    342         * <p>This format is the Java source code format.</p>
    343         *
    344         * <pre>
    345         *   CharUtils.unicodeEscaped(' ') = "\u0020"
    346         *   CharUtils.unicodeEscaped('A') = "\u0041"
    347         * </pre>
    348         *
    349         * @param ch  the character to convert
    350         * @return the escaped Unicode string
    351         */
    352        public static String unicodeEscaped(char ch) {
    353            if (ch < 0x10) {
    354                return "\\u000" + Integer.toHexString(ch);
    355            } else if (ch < 0x100) {
    356                return "\\u00" + Integer.toHexString(ch);
    357            } else if (ch < 0x1000) {
    358                return "\\u0" + Integer.toHexString(ch);
    359            }
    360            return "\\u" + Integer.toHexString(ch);
    361        }
    362
    363        /**
    364         * <p>Converts the string to the Unicode format '\u0020'.</p>
    365         *
    366         * <p>This format is the Java source code format.</p>
    367         *
    368         * <p>If {@code null} is passed in, {@code null} will be returned.</p>
    369         *
    370         * <pre>
    371         *   CharUtils.unicodeEscaped(null) = null
    372         *   CharUtils.unicodeEscaped(' ')  = "\u0020"
    373         *   CharUtils.unicodeEscaped('A')  = "\u0041"
    374         * </pre>
    375         *
    376         * @param ch  the character to convert, may be null
    377         * @return the escaped Unicode string, null if null input
    378         */
    379        public static String unicodeEscaped(Character ch) {
    380            if (ch == null) {
    381                return null;
    382            }
    383            return unicodeEscaped(ch.charValue());
    384        }
    385
    386        //--------------------------------------------------------------------------
    387        /**
    388         * <p>Checks whether the character is ASCII 7 bit.</p>
    389         *
    390         * <pre>
    391         *   CharUtils.isAscii('a')  = true
    392         *   CharUtils.isAscii('A')  = true
    393         *   CharUtils.isAscii('3')  = true
    394         *   CharUtils.isAscii('-')  = true
    395         *   CharUtils.isAscii('\n') = true
    396         *   CharUtils.isAscii('&copy;') = false
    397         * </pre>
    398         *
    399         * @param ch  the character to check
    400         * @return true if less than 128
    401         */
    402        public static boolean isAscii(char ch) {
    403            return ch < 128;
    404        }
    405
    406        /**
    407         * <p>Checks whether the character is ASCII 7 bit printable.</p>
    408         *
    409         * <pre>
    410         *   CharUtils.isAsciiPrintable('a')  = true
    411         *   CharUtils.isAsciiPrintable('A')  = true
    412         *   CharUtils.isAsciiPrintable('3')  = true
    413         *   CharUtils.isAsciiPrintable('-')  = true
    414         *   CharUtils.isAsciiPrintable('\n') = false
    415         *   CharUtils.isAsciiPrintable('&copy;') = false
    416         * </pre>
    417         *
    418         * @param ch  the character to check
    419         * @return true if between 32 and 126 inclusive
    420         */
    421        public static boolean isAsciiPrintable(char ch) {
    422            return ch >= 32 && ch < 127;
    423        }
    424
    425        /**
    426         * <p>Checks whether the character is ASCII 7 bit control.</p>
    427         *
    428         * <pre>
    429         *   CharUtils.isAsciiControl('a')  = false
    430         *   CharUtils.isAsciiControl('A')  = false
    431         *   CharUtils.isAsciiControl('3')  = false
    432         *   CharUtils.isAsciiControl('-')  = false
    433         *   CharUtils.isAsciiControl('\n') = true
    434         *   CharUtils.isAsciiControl('&copy;') = false
    435         * </pre>
    436         *
    437         * @param ch  the character to check
    438         * @return true if less than 32 or equals 127
    439         */
    440        public static boolean isAsciiControl(char ch) {
    441            return ch < 32 || ch == 127;
    442        }
    443
    444        /**
    445         * <p>Checks whether the character is ASCII 7 bit alphabetic.</p>
    446         *
    447         * <pre>
    448         *   CharUtils.isAsciiAlpha('a')  = true
    449         *   CharUtils.isAsciiAlpha('A')  = true
    450         *   CharUtils.isAsciiAlpha('3')  = false
    451         *   CharUtils.isAsciiAlpha('-')  = false
    452         *   CharUtils.isAsciiAlpha('\n') = false
    453         *   CharUtils.isAsciiAlpha('&copy;') = false
    454         * </pre>
    455         *
    456         * @param ch  the character to check
    457         * @return true if between 65 and 90 or 97 and 122 inclusive
    458         */
    459        public static boolean isAsciiAlpha(char ch) {
    460            return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
    461        }
    462
    463        /**
    464         * <p>Checks whether the character is ASCII 7 bit alphabetic upper case.</p>
    465         *
    466         * <pre>
    467         *   CharUtils.isAsciiAlphaUpper('a')  = false
    468         *   CharUtils.isAsciiAlphaUpper('A')  = true
    469         *   CharUtils.isAsciiAlphaUpper('3')  = false
    470         *   CharUtils.isAsciiAlphaUpper('-')  = false
    471         *   CharUtils.isAsciiAlphaUpper('\n') = false
    472         *   CharUtils.isAsciiAlphaUpper('&copy;') = false
    473         * </pre>
    474         *
    475         * @param ch  the character to check
    476         * @return true if between 65 and 90 inclusive
    477         */
    478        public static boolean isAsciiAlphaUpper(char ch) {
    479            return ch >= 'A' && ch <= 'Z';
    480        }
    481
    482        /**
    483         * <p>Checks whether the character is ASCII 7 bit alphabetic lower case.</p>
    484         *
    485         * <pre>
    486         *   CharUtils.isAsciiAlphaLower('a')  = true
    487         *   CharUtils.isAsciiAlphaLower('A')  = false
    488         *   CharUtils.isAsciiAlphaLower('3')  = false
    489         *   CharUtils.isAsciiAlphaLower('-')  = false
    490         *   CharUtils.isAsciiAlphaLower('\n') = false
    491         *   CharUtils.isAsciiAlphaLower('&copy;') = false
    492         * </pre>
    493         *
    494         * @param ch  the character to check
    495         * @return true if between 97 and 122 inclusive
    496         */
    497        public static boolean isAsciiAlphaLower(char ch) {
    498            return ch >= 'a' && ch <= 'z';
    499        }
    500
    501        /**
    502         * <p>Checks whether the character is ASCII 7 bit numeric.</p>
    503         *
    504         * <pre>
    505         *   CharUtils.isAsciiNumeric('a')  = false
    506         *   CharUtils.isAsciiNumeric('A')  = false
    507         *   CharUtils.isAsciiNumeric('3')  = true
    508         *   CharUtils.isAsciiNumeric('-')  = false
    509         *   CharUtils.isAsciiNumeric('\n') = false
    510         *   CharUtils.isAsciiNumeric('&copy;') = false
    511         * </pre>
    512         *
    513         * @param ch  the character to check
    514         * @return true if between 48 and 57 inclusive
    515         */
    516        public static boolean isAsciiNumeric(char ch) {
    517            return ch >= '0' && ch <= '9';
    518        }
    519
    520        /**
    521         * <p>Checks whether the character is ASCII 7 bit numeric.</p>
    522         *
    523         * <pre>
    524         *   CharUtils.isAsciiAlphanumeric('a')  = true
    525         *   CharUtils.isAsciiAlphanumeric('A')  = true
    526         *   CharUtils.isAsciiAlphanumeric('3')  = true
    527         *   CharUtils.isAsciiAlphanumeric('-')  = false
    528         *   CharUtils.isAsciiAlphanumeric('\n') = false
    529         *   CharUtils.isAsciiAlphanumeric('&copy;') = false
    530         * </pre>
    531         *
    532         * @param ch  the character to check
    533         * @return true if between 48 and 57 or 65 and 90 or 97 and 122 inclusive
    534         */
    535        public static boolean isAsciiAlphanumeric(char ch) {
    536            return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9');
    537        }
    538
    539    }