package com.robonobo.common.util; /* * Robonobo Common Utils * Copyright (C) 2008 Will Morton (macavity@well.com) & Ray Hilton (ray@wirestorm.net) * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import java.awt.*; import java.io.*; import java.net.URLDecoder; import java.net.URLEncoder; import java.text.NumberFormat; import java.util.*; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import com.robonobo.common.exceptions.SeekInnerCalmException; /** * Assorted text utils * * @author macavity */ public class TextUtil { public static String[] UNITS = { "", "K", "M", "G", "T", "P", "E" }; private static double[] UNIT_THRESH = { 1d, 1024d, 1048576d, 1073741824d, 1099511627776d, 1125899906842624d, 1152921504606846976d }; // Never instantiate this class private TextUtil() { } public static String formatDurationHMS(long ms) { long hrs = ms / 1000 / 60 / 60; long min = ms / 1000 / 60 % 60; long sec = ms / 1000 % 60; StringBuffer sb = new StringBuffer(); if (hrs > 0) sb.append(leftPad(String.valueOf(hrs), 2, '0')).append(":"); sb.append(leftPad(String.valueOf(min), 2, '0')).append(":"); sb.append(leftPad(String.valueOf(sec), 2, '0')); return sb.toString(); } public static String formatDurationHMSms(long ms) { long hrs = ms / 1000 / 60 / 60; long min = ms / 1000 / 60 % 60; long sec = ms / 1000 % 60; long rms = ms % 1000; return leftPad(String.valueOf(hrs), 2, '0') + ":" + leftPad(String.valueOf(min), 2, '0') + ":" + leftPad(String.valueOf(sec), 2, '0') + ":" + leftPad(String.valueOf(rms), 3, '0'); } public static String formatSizeInBytes(int size) { if (size < 1) return size + "B"; for (int i = 0; i < (UNITS.length - 1); i++) { if (size < UNIT_THRESH[i + 1]) return (int) (size / UNIT_THRESH[i]) + UNITS[i] + "B"; } return size + "B"; } public static String leftPad(String str, int size) { return leftPad(str, size, ' '); } public static String leftPad(String str, int size, char padChar) { if (str.length() >= size) return str; StringBuffer sb = new StringBuffer(); for (int i = 0; i < size - str.length(); i++) { sb.append(padChar); } sb.append(str); return sb.toString(); } public static String rightPad(String str, int size) { if (str.length() >= size) return str; StringBuffer sb = new StringBuffer(); sb.append(str); for (int i = 0; i < size - str.length(); i++) { sb.append(' '); } return sb.toString(); } public static String bytesToHexString(byte[] input) { return bytesToHexString(input, input.length); } /** * * @param input * @param maxLength * max number of bytes to print * @return */ public static String bytesToHexString(byte[] input, int maxLength) { if (input == null) return null; StringBuffer sb = new StringBuffer(); for (int i = 0; i < maxLength; i++) { int digit = input[i] & 0xff; sb.append(Integer.toHexString(digit)); } return sb.toString(); } public static String byteToBinaryString(byte input) { StringBuffer sb = new StringBuffer(); for (int i = 128; i >= 1; i /= 2) { if ((input & i) > 0) sb.append("1"); else sb.append("0"); } return sb.toString(); } public static String padToMinWidth(double num, int minWidth) { NumberFormat nf = NumberFormat.getNumberInstance(); int intDigits = numDigits((int) num); if (intDigits >= minWidth) nf.setMaximumFractionDigits(0); else { boolean hasFracComponent = (int) num != num; if (hasFracComponent) { nf.setMaximumFractionDigits(minWidth - intDigits); nf.setMinimumFractionDigits(minWidth - intDigits); } } return nf.format(num); } public static int numDigits(long val) { // This seems a bit ugly, there must be a more elegant way String s = String.valueOf(val); return s.length(); } public static String rightPadOrTruncate(String str, int resultSz) { if(resultSz < 5) throw new IllegalArgumentException("Can't truncate to <5 chars, won't fit ellipsis in"); if (str == null) str = ""; if (resultSz >= str.length()) return rightPad(str, resultSz); String el = "[...]"; int availSz = resultSz - el.length(); return el + str.substring(str.length() - availSz); } public static String[] getQuotedArgs(String cmdLine) { List args = new ArrayList(); Pattern p = Pattern.compile("\"(.*?)\""); Matcher m = p.matcher(cmdLine); int lastQuotEnd = 0; while (m.find(lastQuotEnd)) { String stuffBefore = cmdLine.substring(lastQuotEnd, m.start()); String[] argsBefore = stuffBefore.trim().split("\\s+"); if (argsBefore.length > 1 || argsBefore[0].length() != 0) Collections.addAll(args, argsBefore); args.add(m.group(1)); lastQuotEnd = m.end(); } String stuffLeft = cmdLine.substring(lastQuotEnd); String[] argsLeft = stuffLeft.trim().split("\\s+"); // If we have a trailing empty string, don't add it if (argsLeft.length > 1 || argsLeft[0].length() != 0) Collections.addAll(args, argsLeft); String[] result = new String[args.size()]; args.toArray(result); return result; } public static String repeat(String pattern, int times) { StringBuffer sb = new StringBuffer(); for (int i = 0; i < times; i++) { sb.append(pattern); } return sb.toString(); } /** * URL-encodes the string as UTF-8 (avoids the need to catch * unsupportedencoding exception) */ public static String urlEncode(String input) { if (input == null) return null; try { return URLEncoder.encode(input, "utf-8"); } catch (UnsupportedEncodingException e) { throw new SeekInnerCalmException(); } } public static String truncate(String str, int length) { if (str.length() <= length) return str; return str.substring(0, length); } /** * URL-decodes the string as UTF-8 (avoids the need to catch * unsupportedencoding exception) */ public static String urlDecode(String input) { if (input == null) return null; try { return URLDecoder.decode(input, "utf-8"); } catch (UnsupportedEncodingException e) { throw new SeekInnerCalmException(); } } /** * Escapes '<' and '>' characters, replacing them with '<' and '>' */ public static String escapeHtml(String input) { if(input == null) return null; return input.replace("<", "<").replace(">", ">"); } public static String readInputStreamToString(InputStream stream) throws IOException { StringBuffer sb = new StringBuffer(stream.available()); byte[] buf = new byte[stream.available()]; for (int n; (n = stream.read(buf)) >= 0;) { sb.append(new String(buf, 0, n)); } return sb.toString(); } /** * Returns (eg) '5 apples', or '1 apple' */ public static String numItems(Collection<?> items, String name) { return numItems(items.size(), name); } public static String numItems(int num, String name) { StringBuffer sb = new StringBuffer(); sb.append(num).append(" ").append(name); if (num != 1) sb.append("s"); return sb.toString(); } public static CharSequence commaSepList(Collection<?> coll) { StringBuffer sb = new StringBuffer(); boolean first = true; for (Object obj : coll) { if (first) first = false; else sb.append(", "); sb.append(obj); } return sb; } /** * f should be in the range 0 - 1 */ public static String percentage(float f) { if (f < 0f || f > 1f) throw new IllegalArgumentException(); return padToMinWidth(f * 100, 3) + "%"; } /** * If the string is longer than maxWidth, limit it to fit within maxWidth * with an ellipsis (...). Will always return at least the string "..." */ public static String limitWithEllipsis(String str, Font font, int maxWidth, Component c) { FontMetrics metrics = c.getFontMetrics(font); int strWidth = metrics.stringWidth(str); if (strWidth <= maxWidth) return str; for (int len = str.length() - 1; len > 0; len--) { String subStr = str.substring(0, len) + "..."; if (metrics.stringWidth(subStr) <= maxWidth) return subStr; } return "..."; } public static String capitalizeFirst(String str) { return str.substring(0, 1).toUpperCase() + str.substring(1); } /** * Returns a hopefully reasonably-decent 64 bit hash. Adapted from * String.hashcode() */ public static long longHash(String str) { long h = 1125899906842597L; // Prime int len = str.length(); for (int i = 0; i < len; i++) { h = 31 * h + str.charAt(i); } return h; } /** * Returns false if the string is null or 0-length, true otherwise */ public static boolean isNonEmpty(String str) { return (str != null && str.length() > 0); } public static boolean isEmpty(String str) { return (str == null) || (str.length() == 0); } public static boolean arrContains(String[] arr, String str) { for(int i=0;i<arr.length;i++) { if(arr[i].equals(str)) return true; } return false; } }