/** * Create a nicely format header string where the given message is surround on both sides by the * marker. Example: "---------- MSG ----------" * * @param msg * @param marker * @param length * @return */ public static String header(String msg, String marker, int length) { int msg_length = msg.length(); length = Math.max(msg_length, length); int border_len = (length - msg_length - 2) / 2; String border = StringUtil.repeat(marker, border_len); boolean add_extra = (border_len + msg_length + 2 + 1 == length); return String.format("%s %s %s%s", border, msg, border, (add_extra ? marker : "")); }
@Override public String toString() { Map<String, Object> m = new ListOrderedMap<String, Object>(); m.put("Scale Factor", this.scale_factor); m.put("Loader Start", this.loaderStartTime); m.put("Loader Stop", this.loaderStopTime); m.put( "Last CloseAuctions", (this.lastCloseAuctionsTime.getTime() > 0 ? this.lastCloseAuctionsTime : null)); m.put("Client Start", this.clientStartTime); m.put("Current Virtual Time", this.currentTime); m.put("Pending ItemCommentResponses", this.pending_commentResponses.size()); // Item Queues Histogram<ItemStatus> itemCounts = new Histogram<ItemStatus>(true); for (ItemStatus status : ItemStatus.values()) { int cnt = 0; switch (status) { case OPEN: cnt = this.items_available.size(); break; case ENDING_SOON: cnt = this.items_endingSoon.size(); break; case WAITING_FOR_PURCHASE: cnt = this.items_waitingForPurchase.size(); break; case CLOSED: cnt = this.items_completed.size(); break; default: assert (false) : "Unexpected " + status; } // SWITCH itemCounts.put(status, cnt); } m.put("Item Queues", itemCounts); return (StringUtil.formatMaps(m)); }
/** * Create a box around some text * * @param str * @param mark * @param max_len * @return */ public static String box(String str, String mark, Integer max_len) { String lines[] = LINE_SPLIT.split(str); if (lines.length == 0) return ""; if (max_len == null) { for (String line : lines) { if (max_len == null || line.length() > max_len) max_len = line.length(); } // FOR } final String top_line = StringUtil.repeat(mark, max_len + 4); // padding final String f = "%s %-" + max_len + "s %s\n"; StringBuilder sb = new StringBuilder(); sb.append(top_line).append("\n"); for (String line : lines) { sb.append(String.format(f, mark, line, mark)); } // FOR sb.append(top_line); return (sb.toString()); }
public void updateItemQueues() { Timestamp currentTime = this.updateAndGetCurrentTime(); assert (currentTime != null); for (LinkedList<ItemInfo> items : allItemSets) { // If the items is already in the completed queue, then we don't need // to do anything with it. if (items == this.items_completed) continue; for (ItemInfo itemInfo : items) { this.addItemToProperQueue(itemInfo, currentTime); } // FOR } if (LOG.isDebugEnabled()) { Map<ItemStatus, Integer> m = new HashMap<ItemStatus, Integer>(); m.put(ItemStatus.OPEN, this.items_available.size()); m.put(ItemStatus.ENDING_SOON, this.items_endingSoon.size()); m.put(ItemStatus.WAITING_FOR_PURCHASE, this.items_waitingForPurchase.size()); m.put(ItemStatus.CLOSED, this.items_completed.size()); LOG.debug( String.format("Updated Item Queues [%s]:\n%s", currentTime, StringUtil.formatMaps(m))); } }
public static String header(String msg) { return StringUtil.header(msg, "-", 100); }
/** * Converts a string to title case (ala Python) * * @param string * @return */ public static String title(String string) { return (StringUtil.title(string, false)); }
/** * Make a box around some text using the given marker character. * * @param str * @param mark * @return */ public static String box(String str, String mark) { return (StringUtil.box(str, mark, null)); }
/** * Make a box around some text. If str has multiple lines, then the box will be the length of the * longest string. * * @param str * @return */ public static String box(String str) { return (StringUtil.box(str, "*", null)); }
/** @author pavlo */ public abstract class StringUtil { public static final String SPACER = " "; public static final String DOUBLE_LINE = StringUtil.repeat("=", 64) + "\n"; public static final String SINGLE_LINE = StringUtil.repeat("-", 64) + "\n"; private static final Pattern LINE_SPLIT = Pattern.compile("\n"); private static final Pattern TITLE_SPLIT = Pattern.compile(" "); private static String CACHE_REPEAT_STR = null; private static Integer CACHE_REPEAT_SIZE = null; private static String CACHE_REPEAT_RESULT = null; private static final double BASE = 1024, KB = BASE, MB = KB * BASE, GB = MB * BASE; private static final DecimalFormat df = new DecimalFormat("#.##"); /** * http://ubuntuforums.org/showpost.php?p=10215516&postcount=5 * * @param bytes * @return */ public static String formatSize(double bytes) { if (bytes >= GB) { return df.format(bytes / GB) + " GB"; } else if (bytes >= MB) { return df.format(bytes / MB) + " MB"; } else if (bytes >= KB) { return df.format(bytes / KB) + " KB"; } return "" + (int) bytes + " bytes"; } /** * @param str * @return */ public static String[] splitLines(String str) { return (str != null ? LINE_SPLIT.split(str) : null); } public static String header(String msg) { return StringUtil.header(msg, "-", 100); } /** * Create a nicely format header string where the given message is surround on both sides by the * marker. Example: "---------- MSG ----------" * * @param msg * @param marker * @param length * @return */ public static String header(String msg, String marker, int length) { int msg_length = msg.length(); length = Math.max(msg_length, length); int border_len = (length - msg_length - 2) / 2; String border = StringUtil.repeat(marker, border_len); boolean add_extra = (border_len + msg_length + 2 + 1 == length); return String.format("%s %s %s%s", border, msg, border, (add_extra ? marker : "")); } /** * Return the MD5 checksum of the given string * * @param input * @return */ public static String md5sum(String input) { MessageDigest digest = null; try { digest = MessageDigest.getInstance("MD5"); } catch (NoSuchAlgorithmException ex) { throw new RuntimeException("Unable to compute md5sum for string", ex); } assert (digest != null); digest.update(input.getBytes()); BigInteger hash = new BigInteger(1, digest.digest()); return (hash.toString(16)); } /** * Split the multi-lined strings into separate columns * * @param strs * @return */ public static String columns(String... strs) { String lines[][] = new String[strs.length][]; String prefixes[] = new String[strs.length]; int max_length = 0; int max_lines = 0; for (int i = 0; i < strs.length; i++) { lines[i] = LINE_SPLIT.split(strs[i]); prefixes[i] = (i == 0 ? "" : " \u2503 "); for (String line : lines[i]) { max_length = Math.max(max_length, line.length()); } // FOR max_lines = Math.max(max_lines, lines[i].length); } // FOR String f = "%-" + max_length + "s"; StringBuilder sb = new StringBuilder(); for (int ii = 0; ii < max_lines; ii++) { for (int i = 0; i < strs.length; i++) { String line = (ii >= lines[i].length ? "" : lines[i][ii]); sb.append(prefixes[i]).append(String.format(f, line)); } // FOR sb.append("\n"); } // FOR return (sb.toString()); } /** * Return key/value maps into a nicely formatted table Delimiter ":", No UpperCase Keys, No Boxing * * @param maps * @return */ public static String formatMaps(Map<?, ?>... maps) { return (formatMaps(":", false, false, false, false, true, true, maps)); } /** * Return key/value maps into a nicely formatted table using the given delimiter No Uppercase * Keys, No Boxing * * @param delimiter * @param maps * @return */ public static String formatMaps(String delimiter, Map<?, ?>... maps) { return (formatMaps(delimiter, false, false, false, false, true, true, maps)); } /** * Return key/value maps into a nicely formatted table The maps are displayed in order from first * to last, and there will be a spacer created between each map. The format for each record is: * * <p><KEY><DELIMITER><SPACING><VALUE> * * <p>If the delimiter is an equal sign, then the format is: * * <p><KEY><SPACING><DELIMITER><VALUE> * * @param delimiter * @param upper Upper-case all keys * @param box Box results * @param border_top TODO * @param border_bottom TODO * @param recursive TODO * @param first_element_title TODO * @param maps * @return */ @SuppressWarnings("unchecked") public static String formatMaps( String delimiter, boolean upper, boolean box, boolean border_top, boolean border_bottom, boolean recursive, boolean first_element_title, Map<?, ?>... maps) { boolean need_divider = (maps.length > 1 || border_bottom || border_top); // Figure out the largest key size so we can get spacing right int max_key_size = 0; int max_title_size = 0; final Map<Object, String[]> map_keys[] = (Map<Object, String[]>[]) new Map[maps.length]; final boolean map_titles[] = new boolean[maps.length]; for (int i = 0; i < maps.length; i++) { Map<?, ?> m = maps[i]; if (m == null) continue; Map<Object, String[]> keys = new HashMap<Object, String[]>(); boolean first = true; for (Object k : m.keySet()) { String k_str[] = LINE_SPLIT.split(k != null ? k.toString() : ""); keys.put(k, k_str); // If the first element has a null value, then we can let it be the title for this map // It's length doesn't affect the other keys, but will affect the total size of the map if (first && first_element_title && m.get(k) == null) { for (String line : k_str) { max_title_size = Math.max(max_title_size, line.length()); } // FOR map_titles[i] = true; } else { for (String line : k_str) { max_key_size = Math.max(max_key_size, line.length()); } // FOR if (first) map_titles[i] = false; } first = false; } // FOR map_keys[i] = keys; } // FOR boolean equalsDelimiter = delimiter.equals("="); final String f = "%-" + (max_key_size + delimiter.length() + 1) + "s" + (equalsDelimiter ? "= " : "") + "%s\n"; // Now make StringBuilder blocks for each map // We do it in this way so that we can get the max length of the values int max_value_size = 0; StringBuilder blocks[] = new StringBuilder[maps.length]; for (int map_i = 0; map_i < maps.length; map_i++) { blocks[map_i] = new StringBuilder(); Map<?, ?> m = maps[map_i]; if (m == null) continue; Map<Object, String[]> keys = map_keys[map_i]; boolean first = true; for (Entry<?, ?> e : m.entrySet()) { String key[] = keys.get(e.getKey()); if (first && map_titles[map_i]) { blocks[map_i].append(StringUtil.join("\n", key)); if (CollectionUtil.last(key).endsWith("\n") == false) blocks[map_i].append("\n"); } else { Object v_obj = e.getValue(); String v = null; if (recursive && v_obj instanceof Map<?, ?>) { v = formatMaps( delimiter, upper, box, border_top, border_bottom, recursive, first_element_title, (Map<?, ?>) v_obj) .trim(); } else if (key.length == 1 && key[0].trim().isEmpty() && v_obj == null) { blocks[map_i].append("\n"); continue; } else if (v_obj == null) { v = "null"; } else { v = v_obj.toString(); } // If the key or value is multiple lines, format them nicely! String value[] = LINE_SPLIT.split(v); int total_lines = Math.max(key.length, value.length); for (int line_i = 0; line_i < total_lines; line_i++) { String k_line = (line_i < key.length ? key[line_i] : ""); if (upper) k_line = k_line.toUpperCase(); String v_line = (line_i < value.length ? value[line_i] : ""); if (line_i == (key.length - 1) && (first == false || (first && v_line.isEmpty() == false))) { if (equalsDelimiter == false && k_line.trim().isEmpty() == false) k_line += ":"; } blocks[map_i].append(String.format(f, k_line, v_line)); if (need_divider) max_value_size = Math.max(max_value_size, v_line.length()); } // FOR if (v.endsWith("\n")) blocks[map_i].append("\n"); } first = false; } } // FOR // Put it all together! // System.err.println("max_title_size=" + max_title_size + ", max_key_size=" + // max_key_size + ", max_value_size=" + max_value_size + ", delimiter=" + delimiter.length()); int total_width = Math.max(max_title_size, (max_key_size + max_value_size + delimiter.length())) + 1; String dividing_line = (need_divider ? repeat("-", total_width) : ""); StringBuilder sb = null; if (maps.length == 1) { sb = blocks[0]; } else { sb = new StringBuilder(); for (int i = 0; i < maps.length; i++) { if (blocks[i].length() == 0) continue; if (i != 0 && maps[i].size() > 0) sb.append(dividing_line).append("\n"); sb.append(blocks[i]); } // FOR } return (box ? StringUtil.box(sb.toString()) : (border_top ? dividing_line + "\n" : "") + sb.toString() + (border_bottom ? dividing_line : "")); } /** * @param maps * @return */ public static String formatMapsBoxed(Map<?, ?>... maps) { return (formatMaps(":", false, true, false, false, true, true, maps)); } /** * Returns the given string repeated the given # of times * * @param str * @param size * @return */ public static String repeat(String str, int size) { // We cache the last call in case they are making repeated calls for the same thing if (CACHE_REPEAT_STR != null && CACHE_REPEAT_STR.equals(str) && CACHE_REPEAT_SIZE.equals(size)) { return (CACHE_REPEAT_RESULT); } StringBuilder sb = new StringBuilder(); for (int i = 0; i < size; i++) sb.append(str); CACHE_REPEAT_RESULT = sb.toString(); CACHE_REPEAT_STR = str; CACHE_REPEAT_SIZE = size; return (CACHE_REPEAT_RESULT); } /** * Make a box around some text. If str has multiple lines, then the box will be the length of the * longest string. * * @param str * @return */ public static String box(String str) { return (StringUtil.box(str, "*", null)); } /** * Make a box around some text using the given marker character. * * @param str * @param mark * @return */ public static String box(String str, String mark) { return (StringUtil.box(str, mark, null)); } /** * Create a box around some text * * @param str * @param mark * @param max_len * @return */ public static String box(String str, String mark, Integer max_len) { String lines[] = LINE_SPLIT.split(str); if (lines.length == 0) return ""; if (max_len == null) { for (String line : lines) { if (max_len == null || line.length() > max_len) max_len = line.length(); } // FOR } final String top_line = StringUtil.repeat(mark, max_len + 4); // padding final String f = "%s %-" + max_len + "s %s\n"; StringBuilder sb = new StringBuilder(); sb.append(top_line).append("\n"); for (String line : lines) { sb.append(String.format(f, mark, line, mark)); } // FOR sb.append(top_line); return (sb.toString()); } /** * Append the prefix to the beginning of each line in str * * @param str * @param prefix * @return */ public static String prefix(String str, String prefix) { String lines[] = LINE_SPLIT.split(str); if (lines.length == 0) return ""; StringBuilder sb = new StringBuilder(); for (String line : lines) { sb.append(prefix).append(line).append("\n"); } // FOR return (sb.toString()); } /** * Abbreviate the given string. The last three chars will be periods * * @param str * @param max * @return */ public static String abbrv(String str, int max) { return (abbrv(str, max, true)); } /** * Abbreviate the given string. If dots, then the last three chars will be periods * * @param str * @param max * @param dots * @return */ public static String abbrv(String str, int max, boolean dots) { int len = str.length(); String ret = null; if (len > max) { ret = (dots ? str.substring(0, max - 3) + "..." : str.substring(0, max)); } else { ret = str; } return (ret); } /** * Converts a string to title case (ala Python) * * @param string * @return */ public static String title(String string) { return (StringUtil.title(string, false)); } /** * Converts a string to title case (ala Python) * * @param string * @param keep_upper If true, then any non-first character that is uppercase stays uppercase * @return */ public static String title(String string, boolean keep_upper) { StringBuilder sb = new StringBuilder(); String add = ""; for (String part : TITLE_SPLIT.split(string)) { sb.append(add).append(part.substring(0, 1).toUpperCase()); int len = part.length(); if (len > 1) { if (keep_upper) { for (int i = 1; i < len; i++) { String c = part.substring(i, i + 1); String up = c.toUpperCase(); sb.append(c.equals(up) ? c : c.toLowerCase()); } // FOR } else { sb.append(part.substring(1).toLowerCase()); } } add = " "; } // FOR return (sb.toString()); } /** * Append SPACER to the front of each line in a string * * @param str * @return */ public static String addSpacers(String str) { StringBuilder sb = new StringBuilder(); for (String line : LINE_SPLIT.split(str)) { sb.append(SPACER).append(line).append("\n"); } // FOR return (sb.toString()); } /** * Python join() * * @param <T> * @param delimiter * @param items * @return */ public static <T> String join(String delimiter, T... items) { return (join(delimiter, Arrays.asList(items))); } public static <T> String join(String delimiter, final Iterator<T> items) { return (join("", delimiter, CollectionUtil.iterable(items))); } /** * Python join() * * @param delimiter * @param items * @return */ public static String join(String delimiter, Iterable<?> items) { return (join("", delimiter, items)); } /** * Python join() with optional prefix * * @param prefix * @param delimiter * @param items * @return */ public static String join(String prefix, String delimiter, Iterable<?> items) { if (items == null) return (""); if (prefix == null) prefix = ""; StringBuilder sb = new StringBuilder(); int i = 0; for (Object x : items) { if (prefix.isEmpty() == false) sb.append(prefix); sb.append(x != null ? x.toString() : x).append(delimiter); i++; } if (i == 0) return ""; sb.delete(sb.length() - delimiter.length(), sb.length()); return sb.toString(); } }
/** * Return key/value maps into a nicely formatted table The maps are displayed in order from first * to last, and there will be a spacer created between each map. The format for each record is: * * <p><KEY><DELIMITER><SPACING><VALUE> * * <p>If the delimiter is an equal sign, then the format is: * * <p><KEY><SPACING><DELIMITER><VALUE> * * @param delimiter * @param upper Upper-case all keys * @param box Box results * @param border_top TODO * @param border_bottom TODO * @param recursive TODO * @param first_element_title TODO * @param maps * @return */ @SuppressWarnings("unchecked") public static String formatMaps( String delimiter, boolean upper, boolean box, boolean border_top, boolean border_bottom, boolean recursive, boolean first_element_title, Map<?, ?>... maps) { boolean need_divider = (maps.length > 1 || border_bottom || border_top); // Figure out the largest key size so we can get spacing right int max_key_size = 0; int max_title_size = 0; final Map<Object, String[]> map_keys[] = (Map<Object, String[]>[]) new Map[maps.length]; final boolean map_titles[] = new boolean[maps.length]; for (int i = 0; i < maps.length; i++) { Map<?, ?> m = maps[i]; if (m == null) continue; Map<Object, String[]> keys = new HashMap<Object, String[]>(); boolean first = true; for (Object k : m.keySet()) { String k_str[] = LINE_SPLIT.split(k != null ? k.toString() : ""); keys.put(k, k_str); // If the first element has a null value, then we can let it be the title for this map // It's length doesn't affect the other keys, but will affect the total size of the map if (first && first_element_title && m.get(k) == null) { for (String line : k_str) { max_title_size = Math.max(max_title_size, line.length()); } // FOR map_titles[i] = true; } else { for (String line : k_str) { max_key_size = Math.max(max_key_size, line.length()); } // FOR if (first) map_titles[i] = false; } first = false; } // FOR map_keys[i] = keys; } // FOR boolean equalsDelimiter = delimiter.equals("="); final String f = "%-" + (max_key_size + delimiter.length() + 1) + "s" + (equalsDelimiter ? "= " : "") + "%s\n"; // Now make StringBuilder blocks for each map // We do it in this way so that we can get the max length of the values int max_value_size = 0; StringBuilder blocks[] = new StringBuilder[maps.length]; for (int map_i = 0; map_i < maps.length; map_i++) { blocks[map_i] = new StringBuilder(); Map<?, ?> m = maps[map_i]; if (m == null) continue; Map<Object, String[]> keys = map_keys[map_i]; boolean first = true; for (Entry<?, ?> e : m.entrySet()) { String key[] = keys.get(e.getKey()); if (first && map_titles[map_i]) { blocks[map_i].append(StringUtil.join("\n", key)); if (CollectionUtil.last(key).endsWith("\n") == false) blocks[map_i].append("\n"); } else { Object v_obj = e.getValue(); String v = null; if (recursive && v_obj instanceof Map<?, ?>) { v = formatMaps( delimiter, upper, box, border_top, border_bottom, recursive, first_element_title, (Map<?, ?>) v_obj) .trim(); } else if (key.length == 1 && key[0].trim().isEmpty() && v_obj == null) { blocks[map_i].append("\n"); continue; } else if (v_obj == null) { v = "null"; } else { v = v_obj.toString(); } // If the key or value is multiple lines, format them nicely! String value[] = LINE_SPLIT.split(v); int total_lines = Math.max(key.length, value.length); for (int line_i = 0; line_i < total_lines; line_i++) { String k_line = (line_i < key.length ? key[line_i] : ""); if (upper) k_line = k_line.toUpperCase(); String v_line = (line_i < value.length ? value[line_i] : ""); if (line_i == (key.length - 1) && (first == false || (first && v_line.isEmpty() == false))) { if (equalsDelimiter == false && k_line.trim().isEmpty() == false) k_line += ":"; } blocks[map_i].append(String.format(f, k_line, v_line)); if (need_divider) max_value_size = Math.max(max_value_size, v_line.length()); } // FOR if (v.endsWith("\n")) blocks[map_i].append("\n"); } first = false; } } // FOR // Put it all together! // System.err.println("max_title_size=" + max_title_size + ", max_key_size=" + // max_key_size + ", max_value_size=" + max_value_size + ", delimiter=" + delimiter.length()); int total_width = Math.max(max_title_size, (max_key_size + max_value_size + delimiter.length())) + 1; String dividing_line = (need_divider ? repeat("-", total_width) : ""); StringBuilder sb = null; if (maps.length == 1) { sb = blocks[0]; } else { sb = new StringBuilder(); for (int i = 0; i < maps.length; i++) { if (blocks[i].length() == 0) continue; if (i != 0 && maps[i].size() > 0) sb.append(dividing_line).append("\n"); sb.append(blocks[i]); } // FOR } return (box ? StringUtil.box(sb.toString()) : (border_top ? dividing_line + "\n" : "") + sb.toString() + (border_bottom ? dividing_line : "")); }