hu.webhejj.commons.text.StringUtils.java Source code

Java tutorial

Introduction

Here is the source code for hu.webhejj.commons.text.StringUtils.java

Source

/*
 *  Copyright Gergely Nagy <greg@webhejj.hu>
 *
 *  Licensed under the Apache License, Version 2.0; 
 *  you may obtain a copy of the License at:
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 */
package hu.webhejj.commons.text;

import hu.webhejj.commons.CompareUtils;

import java.io.UnsupportedEncodingException;
import java.util.Collection;
import java.util.Iterator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.codec.binary.Base64;

public class StringUtils {

    public static final String UTF8 = "UTF-8";

    // replace multiple spaces with a single space
    public static final Pattern multiSpacePattern = Pattern.compile("  +");
    public static final Pattern mapCsvSplitterPattern = Pattern.compile("([^=,]+)=([^=,]+)[,]?");

    // mapping for hex encoding
    private static final byte[] HEX_CHAR_TABLE = { (byte) '0', (byte) '1', (byte) '2', (byte) '3', (byte) '4',
            (byte) '5', (byte) '6', (byte) '7', (byte) '8', (byte) '9', (byte) 'a', (byte) 'b', (byte) 'c',
            (byte) 'd', (byte) 'e', (byte) 'f' };

    /** @return true if String is null or is the empty string after trimming */
    public static boolean isEmpty(String string) {
        return string == null || string.trim().length() == 0;
    }

    /** null-save string equals */
    public static boolean equals(String s1, String s2) {
        return CompareUtils.isEqual(s1, s2);
    }

    /** null-save string compare */
    public static int compare(String s1, String s2) {
        return CompareUtils.compare(s1, s2);
    }

    /** append values to buf separated with the specified separator */
    public static void join(StringBuilder buf, Iterable<?> values, String separator) {
        for (Iterator<?> i = values.iterator(); i.hasNext();) {
            buf.append(i.next());
            if (i.hasNext()) {
                buf.append(separator);
            }
        }
    }

    /** @return string values in the list separated by the specified <code>separator</code> */
    public static String join(Iterable<?> values, String separator) {
        StringBuilder buf = new StringBuilder();
        join(buf, values, separator);
        return buf.toString();
    }

    /** @return string values of objects in the list separated by ", ". Note: no escaping performed! */
    public static String joinCSV(Iterable<?> values) {
        return join(values, ", ");
    }

    /**
     * Code from http://www.javalobby.org/java/forums/t15908.html
     * 
     * @return the Levenshtein distance of two Strings
     */
    public static int compareLevenshtein(String s, String t) {

        int n = s.length();
        int m = t.length();

        if (n == 0) {
            return m;
        }
        if (m == 0) {
            return n;
        }

        int[][] d = new int[n + 1][m + 1];

        for (int i = 0; i <= n; d[i][0] = i++) {
        }
        ;
        for (int j = 1; j <= m; d[0][j] = j++) {
        }
        ;

        for (int i = 1; i <= n; i++) {
            char sc = s.charAt(i - 1);
            for (int j = 1; j <= m; j++) {
                int v = d[i - 1][j - 1];
                if (t.charAt(j - 1) != sc) {
                    v++;
                }
                d[i][j] = Math.min(Math.min(d[i - 1][j] + 1, d[i][j - 1] + 1), v);
            }
        }
        return d[n][m];
    }

    /** @return a <code>String</code> with multiple consecutive spaces replaced with a single space. */
    public static String removeDoubleSpaces(String string) {
        Matcher matcher = multiSpacePattern.matcher(string);
        return matcher.replaceAll(" ");
    }

    /** @return a string representation of an enum set suitable for storage in a database */
    public static <E extends Enum<E>> String enumCollectionToString(Collection<E> enumSet) {

        if (enumSet != null && !enumSet.isEmpty()) {
            StringBuilder buf = new StringBuilder();
            buf.append(",");

            for (Enum<E> value : enumSet) {
                buf.append(value);
                buf.append(",");
            }

            return buf.toString();
        }

        return null;
    }

    /** @return specified bytes in Base64 encoding as UTF-8 string */
    public static String encodeBase64(byte[] bytes) {
        return encodeUtf8(Base64.encodeBase64(bytes));
    }

    /** @return specified UTF-8 string decoded using Base64 */
    public static byte[] decodeBase64(String string) {
        return Base64.decodeBase64(decodeUtf8(string));
    }

    /** @return specified bytes encoded as string of hexadecimal digits */
    public static String encodeHex(byte[] bytes) {

        if (bytes == null) {
            return "";
        }
        try {
            byte[] hex = new byte[2 * bytes.length];
            int index = 0;

            for (byte b : bytes) {
                int v = b & 0xFF;
                hex[index++] = HEX_CHAR_TABLE[v >>> 4];
                hex[index++] = HEX_CHAR_TABLE[v & 0xF];
            }
            return new String(hex, "ASCII");
        } catch (UnsupportedEncodingException e) {
            // should never happen, but still
            throw new RuntimeException("Could not encode to hex", e);
        }
    }

    /** @return string of hexadecimal digits as byte array */
    public static byte[] decodeHex(String hex) {
        if (hex == null) {
            return null;
        }

        int len = hex.length();
        if ((len & 0x01) != 0) {
            throw new RuntimeException("Odd number of characters.");
        }

        byte[] out = new byte[len >> 1];

        // two characters form the hex value.
        for (int i = 0, j = 0; j < len; i++) {
            int f = toHexDigit(hex.charAt(j), j) << 4;
            j++;
            f = f | toHexDigit(hex.charAt(j), j);
            j++;
            out[i] = (byte) (f & 0xFF);
        }

        return out;
    }

    protected static int toHexDigit(char ch, int index) throws RuntimeException {
        int digit = Character.digit(ch, 16);
        if (digit == -1) {
            throw new RuntimeException("Illegal hexadecimal charcter " + ch + " at index " + index);
        }
        return digit;
    }

    /** @return bytes converted to UTF-8 string, catching 
     * UnsupportedEncodingException since this is a pretty basic encoding
     */
    public static String encodeUtf8(byte[] bytes) {
        try {
            return bytes == null ? null : new String(bytes, UTF8);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException("Could not convert bytes to UTF-8 string", e);
        }
    }

    /** @return string converted to UTF-8 bytes, catching 
     * UnsupportedEncodingException since this is a pretty basic encoding
     */
    public static byte[] decodeUtf8(String string) {
        try {
            return string == null ? null : string.getBytes(UTF8);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException("Could get UTF-8 bytes of " + string, e);
        }
    }

    /**
     * chop up strings to chunks of the specified length (last chunk may be shorter)
     */
    public static String[] chop(String string, int length) {
        if (string.length() == 0) {
            return new String[0];
        }
        int chunkCount = string.length() / length + 1;
        String[] chunks = new String[chunkCount];

        for (int i = 0; i < chunkCount; i++) {
            chunks[i] = string.substring(i * length, Math.min(string.length(), (i + 1) * length));
        }
        return chunks;
    }
}