/******************************************************************************* * $Id$ * $Author$ * $Date$ * * Copyright 2002-2003 YAJUL Developers, Joshua Davis, Kent Vogel. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * ******************************************************************************/ package org.yajul.util; import java.io.UnsupportedEncodingException; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Pattern; /** * Provides commonly used string functions. * <hr>User: jdavis * <br>Date: Jul 15, 2003 * <br>Time: 12:17:49 PM * * @author jdavis */ public class StringUtil { public static final String EMPTY = ""; public static final String LF = System.getProperty(SysProps.LINE_SEPARATOR); /** * A logger for this class. */ private static Logger log = Logger.getLogger(StringUtil.class.getName()); /** * Returns the <tt>String</tt> encoded into an array of bytes using the * named charset. This is identical to String.getBytes(charset), except that * it will use the default encoding if the charset is not available. * * @param s the string * @param charset the name of a supported * {@link java.nio.charset.Charset </code>charset<code>} , or null if the default * charset is to be used. * @return The string, encoded in either the default charset or the specified charset. */ public static byte[] getBytes(String s, String charset) { byte[] bytes; try { bytes = (isEmpty(charset)) ? s.getBytes() : s.getBytes(charset); } catch (UnsupportedEncodingException e) { log.log(Level.WARNING,"Encoding " + charset + " is not supported, using default encoding"); bytes = s.getBytes(); } return bytes; } /** * Prints the class name of the object, followed by '@', followed by the identity hash code * of the object, just like java.lang.Object.toString(). * * @param o The object to print. * @return String - The object's default string representation. */ public static String defaultToString(Object o) { return defaultToString(o,true); } /** * Prints the class name of the object, followed by '@', followed by the identity hash code * of the object, just like java.lang.Object.toString(). * * @param o The object to print. * @param hex True for hex, false for decimal * @return String - The object's default string representation. */ public static String defaultToString(Object o,boolean hex) { StringBuffer buf = new StringBuffer(); if (o == null) buf.append("null"); else { buf.append(o.getClass().getName()); buf.append("@"); int identity = System.identityHashCode(o); buf.append(hex ? Integer.toHexString(identity) : Integer.toString(identity)); } return buf.toString(); } /** * Returns true if the string is null or zero length. * * @param str - The string to test. * @return boolean - True if the string is null or zero length. */ public static boolean isEmpty(String str) { return (str == null || str.length() == 0); } /** * @param s a string * @return Returns the string, or a zero length (empty) string if 's' is null. */ public static String nullAsEmpty(String s) { return s == null ? EMPTY : s; } /** * Returns a string containing the hexadecimal representation of the array * of bytes. * * @param bytes The array of bytes to turn into hex. * @return String - The hex string. */ public static String hexString(byte[] bytes) { return hexString(bytes, null); } /** * Returns a string containing the hexadecimal representation of the * array of bytes, separated by an optional string. * * @param bytes The array of bytes to turn into hex. * @param separator The separator string. If null or zero length, no * separator will be used. * @return String - The hex string. */ public static String hexString(byte[] bytes, String separator) { StringBuffer buf = new StringBuffer(); hexString(buf, bytes, separator, true); return buf.toString(); } /** * Convert a string of hexadecimal characters to a byte array. * * @param hexString The hexadecimal string * @return The string of hexadecimal characters as a byte array. */ public static byte[] parseHexString(String hexString) { if (hexString.length() % 2 == 1) { // Odd number of characters: put a zero at the beginning. hexString = "0" + hexString; } return Bytes.parseHex(hexString); } /** * Convert a hexadecimal character to a byte. * * @param n The hex character * @return the byte */ public static byte parseHexChar(char n) { if (n <= '9') return (byte) (n - '0'); if (n <= 'G') return (byte) (n - Bytes.VALUE_UPPERCASE_A); else return (byte) (n - Bytes.VALUE_LOWERCASE_A); } /** * Appends the hex representation of the bytes to the string buffer, separated * by an optional separator string. * * @param bytes The bytes to convert to hex. * @param buf The buffer to append to. * @param separator The separator string. If null or zero length, no * separator will be used. * @param lowerCase True for lower case hex (e.g. 34f0), false for upper * case hex (e.g. 34F0). */ public static void hexString(StringBuffer buf, byte[] bytes, String separator, boolean lowerCase) { char[] out = new char[2]; final char[] chars = (lowerCase) ? Bytes.HEX_CHARS_LOWER : Bytes.HEX_CHARS_UPPER; final char[] sep = (separator != null && separator.length() > 0) ? separator.toCharArray() : null; for (int i = 0; i < bytes.length; i++) { if ((sep != null) && (i > 0)) // Add the separator, if required. buf.append(sep); hexChars(chars, bytes[i], out); buf.append(out); // Append the two hex chars. } } /** * Converts the byte into a two element array of hex characters. * * @param chars The hex character set to use (e.g. HEX_BYTES_LOWER / HEX_BYTES_UPPER). * @param inByte The input byte. * @param out The output array of characters. Length must be >= 2. */ public static void hexChars(final char[] chars, int inByte, char[] out) { out[1] = chars[Bytes.MASK & inByte]; // Get the lower nybble and set the second char. inByte >>= 4; // Shift off the lower nybble. out[0] = chars[Bytes.MASK & inByte]; // Get the upper nybble and set the first char. } /** * Appends the string to the string buffer IFF it is not 'empty' (null or zero length). * * @param string The string to append. * @param buf The string buffer. * @see #isEmpty(String) */ public static void appendIfNotEmpty(String string, StringBuffer buf) { if (!isEmpty(string)) buf.append(string); } /** * Returns the substring before the delimiter string, not including the delimiter string. * * @param string The string to look in. * @param delim The delimiter string. * @return the substring before the delimiter string, not including the delimiter string. */ public static String substringBefore(String string, String delim) { int pos = string.indexOf(delim); if (pos == 0) return null; else if (pos > 0) return string.substring(0, pos); else return string; } /** * Returns the substring after the delimiter string, not including the delimiter string. * * @param string The string to look in. * @param delim The delimiter string. * @return the substring after the delimiter string, not including the delimiter string. */ public static String substringAfter(String string, String delim) { int pos = string.indexOf(delim); if (pos == 0) return string; else if (pos > 0) return string.substring(pos + delim.length()); else return null; } /** * Returns the input string, minus any linefeed at the end. * */ public static String chomp(String s) { if (isEmpty(s)) return s; int len = s.length(); int index = len - 1; char last = s.charAt(index); if (last == '\n') { index--; } if (index >= 0) { last = s.charAt(index); if (last == '\r') { index--; } } if (index < 0) return EMPTY; return s.substring(0, index+1); } /** * Returns a string with the same character repeated. * @param c the character to repeat * @param count the number of times to repeat it. * @return a string with the same character repeated */ public static String repeatChar(char c, int count) { if (count == 0) return EMPTY; StringBuilder sb = new StringBuilder(); repeatChar(c,count,sb); return sb.toString(); } /** * Repeatedly appends the character the specified number of times in the string builder. * @param c the character * @param count the number of times to append it * @param sb the string builder * @return the string builder */ public static StringBuilder repeatChar(char c, int count, StringBuilder sb) { if (count < 0) throw new IllegalArgumentException("count must be > 0!"); if (count == 0) return sb; sb.ensureCapacity(sb.length() + count); for (int i = 0; i < count ; i++) sb.append(c); return sb; } }