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.lang;
018:
019: /**
020: * <p>Operations on char primitives and Character objects.</p>
021: *
022: * <p>This class tries to handle <code>null</code> input gracefully.
023: * An exception will not be thrown for a <code>null</code> input.
024: * Each method documents its behaviour in more detail.</p>
025: *
026: * @author Stephen Colebourne
027: * @since 2.1
028: * @version $Id: CharUtils.java 437554 2006-08-28 06:21:41Z bayard $
029: */
030: public class CharUtils {
031:
032: private static final String CHAR_STRING = "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007"
033: + "\b\t\n\u000b\f\r\u000e\u000f"
034: + "\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017"
035: + "\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f"
036: + "\u0020\u0021\"\u0023\u0024\u0025\u0026\u0027"
037: + "\u0028\u0029\u002a\u002b\u002c\u002d\u002e\u002f"
038: + "\u0030\u0031\u0032\u0033\u0034\u0035\u0036\u0037"
039: + "\u0038\u0039\u003a\u003b\u003c\u003d\u003e\u003f"
040: + "\u0040\u0041\u0042\u0043\u0044\u0045\u0046\u0047"
041: + "\u0048\u0049\u004a\u004b\u004c\u004d\u004e\u004f"
042: + "\u0050\u0051\u0052\u0053\u0054\u0055\u0056\u0057"
043: + "\u0058\u0059\u005a\u005b\\\u005d\u005e\u005f"
044: + "\u0060\u0061\u0062\u0063\u0064\u0065\u0066\u0067"
045: + "\u0068\u0069\u006a\u006b\u006c\u006d\u006e\u006f"
046: + "\u0070\u0071\u0072\u0073\u0074\u0075\u0076\u0077"
047: + "\u0078\u0079\u007a\u007b\u007c\u007d\u007e\u007f";
048:
049: private static final String[] CHAR_STRING_ARRAY = new String[128];
050: private static final Character[] CHAR_ARRAY = new Character[128];
051:
052: /**
053: * <code>
054: </code> linefeed LF ('\n').
055: *
056: * @see <a href="http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#101089">JLF: Escape Sequences
057: * for Character and String Literals</a>
058: * @since 2.2
059: */
060: public static final char LF = '\n';
061:
062: /**
063: * <code>
064: </code> carriage return CR ('\r').
065: *
066: * @see <a href="http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#101089">JLF: Escape Sequences
067: * for Character and String Literals</a>
068: * @since 2.2
069: */
070: public static final char CR = '\r';
071:
072: static {
073: for (int i = 127; i >= 0; i--) {
074: CHAR_STRING_ARRAY[i] = CHAR_STRING.substring(i, i + 1);
075: CHAR_ARRAY[i] = new Character((char) i);
076: }
077: }
078:
079: /**
080: * <p><code>CharUtils</code> instances should NOT be constructed in standard programming.
081: * Instead, the class should be used as <code>CharUtils.toString('c');</code>.</p>
082: *
083: * <p>This constructor is public to permit tools that require a JavaBean instance
084: * to operate.</p>
085: */
086: public CharUtils() {
087: super ();
088: }
089:
090: //-----------------------------------------------------------------------
091: /**
092: * <p>Converts the character to a Character.</p>
093: *
094: * <p>For ASCII 7 bit characters, this uses a cache that will return the
095: * same Character object each time.</p>
096: *
097: * <pre>
098: * CharUtils.toCharacterObject(' ') = ' '
099: * CharUtils.toCharacterObject('A') = 'A'
100: * </pre>
101: *
102: * @param ch the character to convert
103: * @return a Character of the specified character
104: */
105: public static Character toCharacterObject(char ch) {
106: if (ch < CHAR_ARRAY.length) {
107: return CHAR_ARRAY[ch];
108: }
109: return new Character(ch);
110: }
111:
112: /**
113: * <p>Converts the String to a Character using the first character, returning
114: * null for empty Strings.</p>
115: *
116: * <p>For ASCII 7 bit characters, this uses a cache that will return the
117: * same Character object each time.</p>
118: *
119: * <pre>
120: * CharUtils.toCharacterObject(null) = null
121: * CharUtils.toCharacterObject("") = null
122: * CharUtils.toCharacterObject("A") = 'A'
123: * CharUtils.toCharacterObject("BA") = 'B'
124: * </pre>
125: *
126: * @param str the character to convert
127: * @return the Character value of the first letter of the String
128: */
129: public static Character toCharacterObject(String str) {
130: if (StringUtils.isEmpty(str)) {
131: return null;
132: }
133: return toCharacterObject(str.charAt(0));
134: }
135:
136: //-----------------------------------------------------------------------
137: /**
138: * <p>Converts the Character to a char throwing an exception for <code>null</code>.</p>
139: *
140: * <pre>
141: * CharUtils.toChar(null) = IllegalArgumentException
142: * CharUtils.toChar(' ') = ' '
143: * CharUtils.toChar('A') = 'A'
144: * </pre>
145: *
146: * @param ch the character to convert
147: * @return the char value of the Character
148: * @throws IllegalArgumentException if the Character is null
149: */
150: public static char toChar(Character ch) {
151: if (ch == null) {
152: throw new IllegalArgumentException(
153: "The Character must not be null");
154: }
155: return ch.charValue();
156: }
157:
158: /**
159: * <p>Converts the Character to a char handling <code>null</code>.</p>
160: *
161: * <pre>
162: * CharUtils.toChar(null, 'X') = 'X'
163: * CharUtils.toChar(' ', 'X') = ' '
164: * CharUtils.toChar('A', 'X') = 'A'
165: * </pre>
166: *
167: * @param ch the character to convert
168: * @param defaultValue the value to use if the Character is null
169: * @return the char value of the Character or the default if null
170: */
171: public static char toChar(Character ch, char defaultValue) {
172: if (ch == null) {
173: return defaultValue;
174: }
175: return ch.charValue();
176: }
177:
178: //-----------------------------------------------------------------------
179: /**
180: * <p>Converts the String to a char using the first character, throwing
181: * an exception on empty Strings.</p>
182: *
183: * <pre>
184: * CharUtils.toChar(null) = IllegalArgumentException
185: * CharUtils.toChar("") = IllegalArgumentException
186: * CharUtils.toChar("A") = 'A'
187: * CharUtils.toChar("BA") = 'B'
188: * </pre>
189: *
190: * @param str the character to convert
191: * @return the char value of the first letter of the String
192: * @throws IllegalArgumentException if the String is empty
193: */
194: public static char toChar(String str) {
195: if (StringUtils.isEmpty(str)) {
196: throw new IllegalArgumentException(
197: "The String must not be empty");
198: }
199: return str.charAt(0);
200: }
201:
202: /**
203: * <p>Converts the String to a char using the first character, defaulting
204: * the value on empty Strings.</p>
205: *
206: * <pre>
207: * CharUtils.toChar(null, 'X') = 'X'
208: * CharUtils.toChar("", 'X') = 'X'
209: * CharUtils.toChar("A", 'X') = 'A'
210: * CharUtils.toChar("BA", 'X') = 'B'
211: * </pre>
212: *
213: * @param str the character to convert
214: * @param defaultValue the value to use if the Character is null
215: * @return the char value of the first letter of the String or the default if null
216: */
217: public static char toChar(String str, char defaultValue) {
218: if (StringUtils.isEmpty(str)) {
219: return defaultValue;
220: }
221: return str.charAt(0);
222: }
223:
224: //-----------------------------------------------------------------------
225: /**
226: * <p>Converts the character to the Integer it represents, throwing an
227: * exception if the character is not numeric.</p>
228: *
229: * <p>This method coverts the char '1' to the int 1 and so on.</p>
230: *
231: * <pre>
232: * CharUtils.toIntValue('3') = 3
233: * CharUtils.toIntValue('A') = IllegalArgumentException
234: * </pre>
235: *
236: * @param ch the character to convert
237: * @return the int value of the character
238: * @throws IllegalArgumentException if the character is not ASCII numeric
239: */
240: public static int toIntValue(char ch) {
241: if (isAsciiNumeric(ch) == false) {
242: throw new IllegalArgumentException("The character " + ch
243: + " is not in the range '0' - '9'");
244: }
245: return ch - 48;
246: }
247:
248: /**
249: * <p>Converts the character to the Integer it represents, throwing an
250: * exception if the character is not numeric.</p>
251: *
252: * <p>This method coverts the char '1' to the int 1 and so on.</p>
253: *
254: * <pre>
255: * CharUtils.toIntValue('3', -1) = 3
256: * CharUtils.toIntValue('A', -1) = -1
257: * </pre>
258: *
259: * @param ch the character to convert
260: * @param defaultValue the default value to use if the character is not numeric
261: * @return the int value of the character
262: */
263: public static int toIntValue(char ch, int defaultValue) {
264: if (isAsciiNumeric(ch) == false) {
265: return defaultValue;
266: }
267: return ch - 48;
268: }
269:
270: /**
271: * <p>Converts the character to the Integer it represents, throwing an
272: * exception if the character is not numeric.</p>
273: *
274: * <p>This method coverts the char '1' to the int 1 and so on.</p>
275: *
276: * <pre>
277: * CharUtils.toIntValue(null) = IllegalArgumentException
278: * CharUtils.toIntValue('3') = 3
279: * CharUtils.toIntValue('A') = IllegalArgumentException
280: * </pre>
281: *
282: * @param ch the character to convert, not null
283: * @return the int value of the character
284: * @throws IllegalArgumentException if the Character is not ASCII numeric or is null
285: */
286: public static int toIntValue(Character ch) {
287: if (ch == null) {
288: throw new IllegalArgumentException(
289: "The character must not be null");
290: }
291: return toIntValue(ch.charValue());
292: }
293:
294: /**
295: * <p>Converts the character to the Integer it represents, throwing an
296: * exception if the character is not numeric.</p>
297: *
298: * <p>This method coverts the char '1' to the int 1 and so on.</p>
299: *
300: * <pre>
301: * CharUtils.toIntValue(null, -1) = -1
302: * CharUtils.toIntValue('3', -1) = 3
303: * CharUtils.toIntValue('A', -1) = -1
304: * </pre>
305: *
306: * @param ch the character to convert
307: * @param defaultValue the default value to use if the character is not numeric
308: * @return the int value of the character
309: */
310: public static int toIntValue(Character ch, int defaultValue) {
311: if (ch == null) {
312: return defaultValue;
313: }
314: return toIntValue(ch.charValue(), defaultValue);
315: }
316:
317: //-----------------------------------------------------------------------
318: /**
319: * <p>Converts the character to a String that contains the one character.</p>
320: *
321: * <p>For ASCII 7 bit characters, this uses a cache that will return the
322: * same String object each time.</p>
323: *
324: * <pre>
325: * CharUtils.toString(' ') = " "
326: * CharUtils.toString('A') = "A"
327: * </pre>
328: *
329: * @param ch the character to convert
330: * @return a String containing the one specified character
331: */
332: public static String toString(char ch) {
333: if (ch < 128) {
334: return CHAR_STRING_ARRAY[ch];
335: }
336: return new String(new char[] { ch });
337: }
338:
339: /**
340: * <p>Converts the character to a String that contains the one character.</p>
341: *
342: * <p>For ASCII 7 bit characters, this uses a cache that will return the
343: * same String object each time.</p>
344: *
345: * <p>If <code>null</code> is passed in, <code>null</code> will be returned.</p>
346: *
347: * <pre>
348: * CharUtils.toString(null) = null
349: * CharUtils.toString(' ') = " "
350: * CharUtils.toString('A') = "A"
351: * </pre>
352: *
353: * @param ch the character to convert
354: * @return a String containing the one specified character
355: */
356: public static String toString(Character ch) {
357: if (ch == null) {
358: return null;
359: }
360: return toString(ch.charValue());
361: }
362:
363: //--------------------------------------------------------------------------
364: /**
365: * <p>Converts the string to the unicode format '\u0020'.</p>
366: *
367: * <p>This format is the Java source code format.</p>
368: *
369: * <pre>
370: * CharUtils.unicodeEscaped(' ') = "\u0020"
371: * CharUtils.unicodeEscaped('A') = "\u0041"
372: * </pre>
373: *
374: * @param ch the character to convert
375: * @return the escaped unicode string
376: */
377: public static String unicodeEscaped(char ch) {
378: if (ch < 0x10) {
379: return "\\u000" + Integer.toHexString(ch);
380: } else if (ch < 0x100) {
381: return "\\u00" + Integer.toHexString(ch);
382: } else if (ch < 0x1000) {
383: return "\\u0" + Integer.toHexString(ch);
384: }
385: return "\\u" + Integer.toHexString(ch);
386: }
387:
388: /**
389: * <p>Converts the string to the unicode format '\u0020'.</p>
390: *
391: * <p>This format is the Java source code format.</p>
392: *
393: * <p>If <code>null</code> is passed in, <code>null</code> will be returned.</p>
394: *
395: * <pre>
396: * CharUtils.unicodeEscaped(null) = null
397: * CharUtils.unicodeEscaped(' ') = "\u0020"
398: * CharUtils.unicodeEscaped('A') = "\u0041"
399: * </pre>
400: *
401: * @param ch the character to convert, may be null
402: * @return the escaped unicode string, null if null input
403: */
404: public static String unicodeEscaped(Character ch) {
405: if (ch == null) {
406: return null;
407: }
408: return unicodeEscaped(ch.charValue());
409: }
410:
411: //--------------------------------------------------------------------------
412: /**
413: * <p>Checks whether the character is ASCII 7 bit.</p>
414: *
415: * <pre>
416: * CharUtils.isAscii('a') = true
417: * CharUtils.isAscii('A') = true
418: * CharUtils.isAscii('3') = true
419: * CharUtils.isAscii('-') = true
420: * CharUtils.isAscii('\n') = true
421: * CharUtils.isAscii('©') = false
422: * </pre>
423: *
424: * @param ch the character to check
425: * @return true if less than 128
426: */
427: public static boolean isAscii(char ch) {
428: return ch < 128;
429: }
430:
431: /**
432: * <p>Checks whether the character is ASCII 7 bit printable.</p>
433: *
434: * <pre>
435: * CharUtils.isAsciiPrintable('a') = true
436: * CharUtils.isAsciiPrintable('A') = true
437: * CharUtils.isAsciiPrintable('3') = true
438: * CharUtils.isAsciiPrintable('-') = true
439: * CharUtils.isAsciiPrintable('\n') = false
440: * CharUtils.isAsciiPrintable('©') = false
441: * </pre>
442: *
443: * @param ch the character to check
444: * @return true if between 32 and 126 inclusive
445: */
446: public static boolean isAsciiPrintable(char ch) {
447: return ch >= 32 && ch < 127;
448: }
449:
450: /**
451: * <p>Checks whether the character is ASCII 7 bit control.</p>
452: *
453: * <pre>
454: * CharUtils.isAsciiControl('a') = false
455: * CharUtils.isAsciiControl('A') = false
456: * CharUtils.isAsciiControl('3') = false
457: * CharUtils.isAsciiControl('-') = false
458: * CharUtils.isAsciiControl('\n') = true
459: * CharUtils.isAsciiControl('©') = false
460: * </pre>
461: *
462: * @param ch the character to check
463: * @return true if less than 32 or equals 127
464: */
465: public static boolean isAsciiControl(char ch) {
466: return ch < 32 || ch == 127;
467: }
468:
469: /**
470: * <p>Checks whether the character is ASCII 7 bit alphabetic.</p>
471: *
472: * <pre>
473: * CharUtils.isAsciiAlpha('a') = true
474: * CharUtils.isAsciiAlpha('A') = true
475: * CharUtils.isAsciiAlpha('3') = false
476: * CharUtils.isAsciiAlpha('-') = false
477: * CharUtils.isAsciiAlpha('\n') = false
478: * CharUtils.isAsciiAlpha('©') = false
479: * </pre>
480: *
481: * @param ch the character to check
482: * @return true if between 65 and 90 or 97 and 122 inclusive
483: */
484: public static boolean isAsciiAlpha(char ch) {
485: return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
486: }
487:
488: /**
489: * <p>Checks whether the character is ASCII 7 bit alphabetic upper case.</p>
490: *
491: * <pre>
492: * CharUtils.isAsciiAlphaUpper('a') = false
493: * CharUtils.isAsciiAlphaUpper('A') = true
494: * CharUtils.isAsciiAlphaUpper('3') = false
495: * CharUtils.isAsciiAlphaUpper('-') = false
496: * CharUtils.isAsciiAlphaUpper('\n') = false
497: * CharUtils.isAsciiAlphaUpper('©') = false
498: * </pre>
499: *
500: * @param ch the character to check
501: * @return true if between 65 and 90 inclusive
502: */
503: public static boolean isAsciiAlphaUpper(char ch) {
504: return ch >= 'A' && ch <= 'Z';
505: }
506:
507: /**
508: * <p>Checks whether the character is ASCII 7 bit alphabetic lower case.</p>
509: *
510: * <pre>
511: * CharUtils.isAsciiAlphaLower('a') = true
512: * CharUtils.isAsciiAlphaLower('A') = false
513: * CharUtils.isAsciiAlphaLower('3') = false
514: * CharUtils.isAsciiAlphaLower('-') = false
515: * CharUtils.isAsciiAlphaLower('\n') = false
516: * CharUtils.isAsciiAlphaLower('©') = false
517: * </pre>
518: *
519: * @param ch the character to check
520: * @return true if between 97 and 122 inclusive
521: */
522: public static boolean isAsciiAlphaLower(char ch) {
523: return ch >= 'a' && ch <= 'z';
524: }
525:
526: /**
527: * <p>Checks whether the character is ASCII 7 bit numeric.</p>
528: *
529: * <pre>
530: * CharUtils.isAsciiNumeric('a') = false
531: * CharUtils.isAsciiNumeric('A') = false
532: * CharUtils.isAsciiNumeric('3') = true
533: * CharUtils.isAsciiNumeric('-') = false
534: * CharUtils.isAsciiNumeric('\n') = false
535: * CharUtils.isAsciiNumeric('©') = false
536: * </pre>
537: *
538: * @param ch the character to check
539: * @return true if between 48 and 57 inclusive
540: */
541: public static boolean isAsciiNumeric(char ch) {
542: return ch >= '0' && ch <= '9';
543: }
544:
545: /**
546: * <p>Checks whether the character is ASCII 7 bit numeric.</p>
547: *
548: * <pre>
549: * CharUtils.isAsciiAlphanumeric('a') = true
550: * CharUtils.isAsciiAlphanumeric('A') = true
551: * CharUtils.isAsciiAlphanumeric('3') = true
552: * CharUtils.isAsciiAlphanumeric('-') = false
553: * CharUtils.isAsciiAlphanumeric('\n') = false
554: * CharUtils.isAsciiAlphanumeric('©') = false
555: * </pre>
556: *
557: * @param ch the character to check
558: * @return true if between 48 and 57 or 65 and 90 or 97 and 122 inclusive
559: */
560: public static boolean isAsciiAlphanumeric(char ch) {
561: return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')
562: || (ch >= '0' && ch <= '9');
563: }
564:
565: }
|