package prefuse.util; import java.awt.FontMetrics; import java.io.IOException; import java.io.PrintWriter; import java.io.StreamTokenizer; import java.io.StringReader; import java.io.StringWriter; import java.lang.reflect.Array; import java.util.Hashtable; /** * Library of utility routines pertaining to Strings. * * @author <a href="http://jheer.org">jeffrey heer</a> */ public class StringLib { private StringLib() { // prevent instantiation } /** * Given an array object, create a String showing the contents * of the array using a "[a[0], a[1], ..., a[a.length-1]]" format. * @param a the array object * @return the array string */ public static final String getArrayString(Object a) { StringBuffer sbuf = new StringBuffer(); sbuf.append('['); int size = Array.getLength(a); for ( int i=0; i<size; ++i ) { if ( i>0 ) sbuf.append(", "); sbuf.append(Array.get(a, i)); } sbuf.append(']'); return sbuf.toString(); } /** * Format the given number as a String, including the given number of * decimal places. * @param number the number to format * @param decimalPlaces the number of decimal places to include * @return the formatted String */ public static String formatNumber(double number, int decimalPlaces) { String s = String.valueOf(number); int idx1 = s.indexOf('.'); if ( idx1 == -1 ) { return s; } else { int idx2 = s.indexOf('E'); int dp = decimalPlaces + (idx2>=0 ? 0 : 1); String t = s.substring(0, Math.min(idx1+dp, s.length())); if ( idx2 >= 0 ) t += s.substring(idx2); return t; } } /** * Capitalize all letters preceded by whitespace, and lower case * all other letters. * @param s the String to capitalize * @return the capitalized string */ public static String capitalizeFirstOnly(String s) { if ( s == null ) return null; if ( s.length() == 0 ) return s; StringBuffer sbuf = new StringBuffer(); char c = s.charAt(0); sbuf.append(Character.toUpperCase(c)); boolean space = Character.isWhitespace(c); for ( int i=1; i<s.length(); ++i ) { c = s.charAt(i); if ( Character.isWhitespace(c) ) { space = true; } else if ( space ) { c = Character.toUpperCase(c); space = false; } else { c = Character.toLowerCase(c); } sbuf.append(c); } return sbuf.toString(); } /** * Get the stack trace of the given Throwable as a String. * @param t the Throwable * @return the stack trace of the Throwable */ public static String getStackTrace(Throwable t) { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); t.printStackTrace(pw); pw.close(); return sw.toString(); } // ------------------------------------------------------------------------ // Abbreviation Methods private static final String SUFFIX = "suffix"; private static final String PREFIX = "prefix"; private static Hashtable prefixSuffixT = new Hashtable(); static { prefixSuffixT.put( "mr", PREFIX ); prefixSuffixT.put( "mr.", PREFIX ); prefixSuffixT.put( "dr", PREFIX ); prefixSuffixT.put( "dr.", PREFIX ); prefixSuffixT.put( "lt", PREFIX ); prefixSuffixT.put( "lt.", PREFIX ); prefixSuffixT.put( "gen", PREFIX ); prefixSuffixT.put( "gen.", PREFIX ); prefixSuffixT.put( "sgt", PREFIX ); prefixSuffixT.put( "sgt.", PREFIX ); prefixSuffixT.put( "cmdr", PREFIX ); prefixSuffixT.put( "cmdr.", PREFIX ); prefixSuffixT.put( "cpt", PREFIX ); prefixSuffixT.put( "cpt.", PREFIX ); prefixSuffixT.put( "ii", SUFFIX ); prefixSuffixT.put( "iii", SUFFIX ); prefixSuffixT.put( "iv", SUFFIX ); prefixSuffixT.put( "jr", SUFFIX ); prefixSuffixT.put( "jr.", SUFFIX ); prefixSuffixT.put( "sr", SUFFIX ); prefixSuffixT.put( "sr.", SUFFIX ); } /** * Abbreviate a String by simply truncating it. * @param str the String to abbreviate * @param fm the FontMetrics for measuring the String length * @param width the maximum string width, in pixels * @return an abbreviated String */ public static String abbreviate(String str, FontMetrics fm, int width) { int lastblank = 0, nchars = 0, cumx = 0; while ( cumx < width && nchars < str.length() ) { if ( Character.isWhitespace(str.charAt(nchars)) ) { lastblank = nchars; } cumx += fm.charWidth(str.charAt(nchars)); nchars++; } if ( nchars < str.length() && lastblank > 0 ) { nchars = lastblank; } return ( nchars > 0 ? str.substring(0, nchars) : str ); } /** * Abbreviate a String as a given name. * @param str the String to abbreviate * @param fm the FontMetrics for measuring the String length * @param width the maximum string width, in pixels * @return an abbreviated String */ public static String abbreviateName(String str, FontMetrics fm, int width) { if (fm.stringWidth(str) > width) str = abbreviateName(str, false); if (fm.stringWidth(str) > width) str = abbreviateName(str, true); return str; } /** * String abbreviation helper method for name strings. * @param inString the String to abbreviate * @param lastOnly true to include only the last name, false otherwise * @return an abbreviated name */ private static String abbreviateName(String inString, boolean lastOnly) { StringReader in = new StringReader(inString); StreamTokenizer p = new StreamTokenizer(in); p.wordChars('&', '&'); p.wordChars('@', '@'); p.wordChars(':', ':'); p.ordinaryChar(','); p.ordinaryChar('-'); int c; String lastNameHold = null; String lastInitialHold = null; StringBuffer outString = new StringBuffer(); try { out: while (true) { c = p.nextToken(); switch (c) { case StreamTokenizer.TT_EOF: break out; case StreamTokenizer.TT_EOL: System.err.println("warning: unexpected EOL token"); break; case StreamTokenizer.TT_NUMBER: break; case ',': break out; case StreamTokenizer.TT_WORD: if (p.sval.endsWith(":")) outString.append(p.sval + " "); else if (prefixSuffixT.get(p.sval.toLowerCase()) == null) { if (!lastOnly) { if (lastInitialHold != null) outString.append(lastInitialHold); lastInitialHold = p.sval.substring(0,1)+". "; } lastNameHold = p.sval; } break; default: break; } } outString.append(lastNameHold); } catch (IOException e) { e.printStackTrace(); } return outString.toString(); } } // end of class StringLib