usr/src/java/util/org/opensolaris/os/vp/util/misc/TextUtil.java
changeset 219 57841c113efe
parent 78 6336fcea8db0
child 243 979bb698977b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/util/org/opensolaris/os/vp/util/misc/TextUtil.java	Fri Feb 20 13:56:20 2009 -0500
@@ -0,0 +1,447 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+package org.opensolaris.os.vp.util.misc;
+
+import java.util.*;
+import java.util.regex.*;
+
+public class TextUtil {
+    //
+    // Static methods
+    //
+
+    /**
+     * Returns the base portion of a fully-qualified class name.
+     */
+    public static String getClassBaseName(String className) {
+	return className.replaceFirst(".*\\.", "");
+    }
+
+    /**
+     * Returns the base portion of a fully-qualified class name.
+     */
+    public static String getClassBaseName(Class clazz) {
+	return getClassBaseName(clazz.getName());
+    }
+
+    /**
+     * Returns the package portion of a fully-qualified class name.
+     */
+    public static String getPackageName(String name) {
+	return name.replaceFirst("\\.?\\.*[^.]*$", "");
+    }
+
+    /**
+     * Returns the package portion of a fully-qualified class name.
+     */
+    public static String getPackageName(Class clazz) {
+	return getPackageName(clazz.getName());
+    }
+
+    /**
+     * Returns a random alpha {@code String} with length between {@code minLen}
+     * and {@code maxLen}.
+     */
+    public static String getRandomAlphaString(int minLen, int maxLen) {
+	StringBuffer buffer = new StringBuffer();
+	int length = (int)(Math.random() * (maxLen - minLen + 1)) + minLen;
+	for (int j = 0; j < length; j++) {
+	    char c = (char)((Math.random() * 26) + 97);
+	    buffer.append(c);
+	}
+	return buffer.toString();
+    }
+
+    /**
+     * Replace characters with special meaning to HTML with their HTML entity
+     * equivalents.
+     */
+    public static String escapeHTMLChars(String text) {
+	StringBuffer buffer = new StringBuffer();
+
+	for (char c : text.toCharArray()) {
+	    switch (c) {
+		case '<':
+		    buffer.append("&lt;");
+		    break;
+
+		case '>':
+		    buffer.append("&gt;");
+		    break;
+
+		case '\"':
+		    buffer.append("&quot;");
+		    break;
+
+		case '\'':
+		    buffer.append("&#039;");
+		    break;
+
+		case '\\':
+		    buffer.append("&#092;");
+		    break;
+
+		case '&':
+		    buffer.append("&amp;");
+		    break;
+
+		case '\n':
+		    buffer.append("<br/>");
+		    break;
+
+		default:
+		    buffer.append(c);
+	    }
+	}
+
+	return buffer.toString();
+    }
+
+    /**
+     * Splits the given string into lines.
+     *
+     * @param	    text
+     *		    the text to format
+     *
+     * @param	    width
+     *		    the maximum width of each line
+     *
+     * @param	    indent1
+     *		    the indent to put on the first line
+     *
+     * @param	    indent2
+     *		    the indent to put on the second and remaining lines
+     *
+     * @param	    forceBreak
+     *		    whether to force a break in the middle of a word
+     *		    if the length of the word is greater than
+     *		    <code>width</code>
+     *
+     * @return	    a wrapped string separated by newlines
+     */
+    public static String format(String text, int width,
+	String indent1, String indent2, boolean forceBreak) {
+
+	if (text == null) {
+	    return text;
+	}
+
+	// Replace newlines
+	text = text.replaceAll("\\s*[\\r\\n]\\s*", " ");
+
+	StringBuffer buffer = new StringBuffer();
+
+	String indent = indent1;
+	int w = width - indent.length();
+	if (w < 1) {
+	    w = 1;
+	}
+
+	for (int i = 0; text.length() > 0; i++) {
+	    String regex = "^\\s*(.{1," + w + "})($|\\s+.*)";
+	    String[] groups = match(text, regex);
+
+	    if (groups == null) {
+		// Can't break line on whitespace without exceeding width
+		if (forceBreak) {
+		    // Break line in middle of word
+		    regex = "^\\s*(.{1," + w + "})(.*)";
+		} else {
+		    // Break line at next whitespace
+		    regex = "^\\s*(.+?)($|\\s+.*)";
+		}
+
+		groups = match(text, regex);
+	    }
+
+	    if (i != 0) {
+		buffer.append("\n");
+	    }
+
+	    buffer.append(indent).append(groups[1].trim());
+	    text = groups[2];
+
+	    if (i == 0) {
+		indent = indent2;
+		w = width - indent.length();
+		if (w < 1) {
+		    w = 1;
+		}
+	    }
+	}
+
+	return buffer.toString();
+    }
+
+    /**
+     * Shortcut for:
+     * <p>
+     *	 <code>
+     *	   {@link #format(String,int,String,String,boolean) format}
+     *	   (text, width, "", "", forceBreak);
+     *	 </code>
+     * </p>
+     */
+    public static String format(String text, int width, boolean forceBreak) {
+	return format(text, width, "", "", forceBreak);
+    }
+
+    public static boolean isPrintable(char c) {
+	return c >= 32 && c <= 126;
+    }
+
+    public static String join(String delim, Object... list) {
+	StringBuffer buffer = new StringBuffer();
+
+	for (int i = 0; i < list.length; i++) {
+	    if (i != 0 && delim != null) {
+		buffer.append(delim);
+	    }
+	    buffer.append(list[i]);
+	}
+
+	return buffer.toString();
+    }
+
+    public static String join(String delim, byte... list) {
+	Byte[] array = new Byte[list.length];
+	for (int i = 0; i < array.length; i++) {
+	    array[i] = list[i];
+	}
+	return join(delim, (Object[])array);
+    }
+
+    public static String join(String delim, char... list) {
+	Character[] array = new Character[list.length];
+	for (int i = 0; i < array.length; i++) {
+	    array[i] = list[i];
+	}
+	return join(delim, (Object[])array);
+    }
+
+    public static String join(String delim, double... list) {
+	Double[] array = new Double[list.length];
+	for (int i = 0; i < array.length; i++) {
+	    array[i] = list[i];
+	}
+	return join(delim, (Object[])array);
+    }
+
+    public static String join(String delim, float... list) {
+	Float[] array = new Float[list.length];
+	for (int i = 0; i < array.length; i++) {
+	    array[i] = list[i];
+	}
+	return join(delim, (Object[])array);
+    }
+
+    public static String join(String delim, int... list) {
+	Integer[] array = new Integer[list.length];
+	for (int i = 0; i < array.length; i++) {
+	    array[i] = list[i];
+	}
+	return join(delim, (Object[])array);
+    }
+
+    public static String join(String delim, long... list) {
+	Long[] array = new Long[list.length];
+	for (int i = 0; i < array.length; i++) {
+	    array[i] = list[i];
+	}
+	return join(delim, (Object[])array);
+    }
+
+    public static String join(String delim, short... list) {
+	Short[] array = new Short[list.length];
+	for (int i = 0; i < array.length; i++) {
+	    array[i] = list[i];
+	}
+	return join(delim, (Object[])array);
+    }
+
+    public static String join(String delim, Collection list) {
+	return join(delim, list.toArray());
+    }
+
+    /**
+     * Matches the given string against the given regular expression,
+     * returning an array of the matched regular expression groups.
+     *
+     * @param	    text
+     *		    the String to which to apply the regular
+     *		    expression
+     *
+     * @param	    regex
+     *		    a regular expression containing groups
+     *
+     * @return	    an array of the matched regular expression groups
+     *		    (group 0 is the entire pattern), if the given
+     *		    pattern matched, or {@code null} if the
+     *		    pattern did not match
+     *
+     * @exception   PatternSyntaxException
+     *		    if the given pattern was malformed
+     */
+    public static String[] match(String text, String regex)
+	throws PatternSyntaxException {
+
+	Matcher matcher = Pattern.compile(regex).matcher(text);
+	if (!matcher.matches()) {
+	    return null;
+	}
+
+	String[] groups = new String[matcher.groupCount() + 1];
+	for (int i = 0; i < groups.length; i++) {
+	    groups[i] = matcher.group(i);
+	}
+
+	return groups;
+    }
+
+    /**
+     * Splits the given text into fields.
+     *
+     * @param	    delim
+     *		    the regular expression delimiter for each field
+     *
+     * @param	    text
+     *		    the text to split
+     *
+     * @param	    quotes
+     *		    the characters that indicate a grouping of text,
+     *		    eg. single quotes ("<code>'</code>") or double
+     *		    quotes ("<code>"</code>"), etc., or
+     *		    <code>null</code> for no quotes
+     *
+     * @param	    quoteEsc
+     *		    an expression that can precede a quote character
+     *		    so that it is interpreted normally, rather than as
+     *		    a quote character, or <code>null</code> if no such
+     *		    escape character is used
+     *
+     * @return	    the resulting fields
+     */
+    public static String[] split(
+	String delim, String text, String quotes, String quoteEsc) {
+
+	// Create the matching regular expression
+	int ngroups = 0;
+	int quoteGroup = -1;
+	int quoteEscGroup = -1;
+
+	StringBuffer reBuffer = new StringBuffer("^(.*?)(");
+	int fieldGroup = ++ngroups;
+	ngroups++;
+
+	if (quotes != null) {
+	    if (quoteEsc != null) {
+		reBuffer.append("(\\Q").append(quoteEsc).append("\\E").
+		    append("[").append(quotes).append("])|");
+		quoteEscGroup = ++ngroups;
+	    }
+	    reBuffer.append("([").append(quotes).append("])|");
+	    quoteGroup = ++ngroups;
+	}
+	reBuffer.append("(").append(delim).append("))(.*)");
+	int delimGroup = ++ngroups;
+	int textGroup = ++ngroups;
+
+	String regex = reBuffer.toString();
+
+	List<String> fields = new ArrayList<String>();
+
+	// Build the field
+	StringBuffer field = new StringBuffer();
+
+	boolean inQuote = false;
+	String curQuote = null;
+	while (text != null && text.length() > 0) {
+
+	    String[] groups = match(text, regex);
+
+	    if (groups == null) {
+		field.append(text);
+		text = null;
+	    } else {
+
+		field.append(groups[fieldGroup]);
+
+		// Remaining text
+		text = groups[textGroup];
+
+		// Was a delimiter reached?
+		if (groups[delimGroup] != null) {
+		    if (inQuote) {
+			field.append(groups[delimGroup]);
+		    } else {
+			fields.add(field.toString());
+			field.setLength(0);
+		    }
+		} else
+
+		try {
+		    String quote = groups[quoteGroup];
+		   // Was a quote reached?
+		    if (quote != null) {
+			if (inQuote) {
+			    if (quote.equals(curQuote)) {
+				inQuote = false;
+			    } else {
+				field.append(quote);
+			    }
+			} else {
+			    inQuote = true;
+			    curQuote = quote;
+			}
+		    } else
+
+		    // Was an escaped quote reached?
+		    if (groups[quoteEscGroup] != null) {
+			field.append(quotes);
+		    }
+		}
+		catch (ArrayIndexOutOfBoundsException ignore) {}
+	    }
+	}
+
+	fields.add(field.toString());
+
+	return fields.toArray(new String[fields.size()]);
+    }
+
+    public static String toJavaMethodName(String... words) {
+	StringBuffer buffer = new StringBuffer();
+	for (String word : words) {
+	    try {
+		buffer.append(word.substring(0, 1).toUpperCase());
+		buffer.append(word.substring(1).toLowerCase());
+	    } catch (IndexOutOfBoundsException ignore) {
+	    }
+	}
+	return buffer.toString();
+    }
+}