/* * Copyright (c) 2013-2016 Chris Newland. * Licensed under https://github.com/AdoptOpenJDK/jitwatch/blob/master/LICENSE-BSD * Instructions: https://github.com/AdoptOpenJDK/jitwatch/wiki */ package org.adoptopenjdk.jitwatch.util; import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.C_DOT; import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.C_DOUBLE_QUOTE; import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.C_EQUALS; import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.C_QUOTE; import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.C_SPACE; import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_APOSTROPHE; import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_CLOSE_ANGLE; import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_COLON; import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_DOT; import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_EMPTY; import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_ENTITY_APOS; import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_ENTITY_GT; import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_ENTITY_LT; import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_ESCAPED_DOT; import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_NEWLINE; import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_OPEN_ANGLE; import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_SPACE; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; public final class StringUtil { private static final DecimalFormat DF_THOUSANDS = new DecimalFormat("#,###"); private StringUtil() { } public static String formatTimestamp(long stamp, boolean showMillis) { long stampCopy = stamp; long dayMillis = 24L * 60L * 60_000L; long hourMillis = 60L * 60_000L; long minuteMillis = 60_000L; long secondMillis = 1_000L; long days = (long) Math.floor(stampCopy / dayMillis); stampCopy -= days * dayMillis; long hours = (long) Math.floor(stampCopy / hourMillis); stampCopy -= hours * hourMillis; long minutes = (long) Math.floor(stampCopy / minuteMillis); stampCopy -= minutes * minuteMillis; long seconds = (long) Math.floor(stampCopy / secondMillis); stampCopy -= seconds * secondMillis; long millis = stampCopy; StringBuilder sb = new StringBuilder(); if (days > 0) { sb.append(days).append("d "); } sb.append(padZero(hours, 2)).append(S_COLON); sb.append(padZero(minutes, 2)).append(S_COLON); sb.append(padZero(seconds, 2)); if (showMillis) { sb.append(S_DOT).append(padZero(millis, 3)); } return sb.toString(); } public static String replaceXMLEntities(String input) { String result = null; if (input != null) { result = input.replace(S_ENTITY_LT, S_OPEN_ANGLE).replace(S_ENTITY_GT, S_CLOSE_ANGLE).replace(S_ENTITY_APOS, S_APOSTROPHE); } return result; } public static String repeat(char c, int count) { StringBuilder builder = new StringBuilder(); for (int i = 0; i < count; i++) { builder.append(c); } return builder.toString(); } public static String rtrim(String string) { return string.replaceAll("\\s+$", ""); } public static String alignRight(long num, int width) { return pad(Long.toString(num), width, C_SPACE, true); } public static String alignRight(String str, int width) { return pad(str, width, C_SPACE, true); } public static String alignLeft(long num, int width) { return pad(Long.toString(num), width, C_SPACE, false); } public static String alignLeft(String str, int width) { return pad(str, width, C_SPACE, false); } public static String padZero(long num, int width) { return pad(Long.toString(num), width, '0', true); } public static String pad(String str, int width, char padding, boolean left) { StringBuilder sb = new StringBuilder(); if (str != null) { int len = str.length(); if (!left) { sb.append(str); } if (len < width) { for (int i = 0; i < width - len; i++) { sb.append(padding); } } if (left) { sb.append(str); } } return sb.toString(); } public static List<String> textToList(String text, String split) { List<String> result = new ArrayList<>(); if (text != null) { String[] lines = text.split(split); for (String line : lines) { if (line.trim().length() > 0) { result.add(line); } } } return result; } public static String listToText(List<String> list, String join) { StringBuilder builder = new StringBuilder(); for (String line : list) { builder.append(line).append(join); } if (builder.length() > 0) { builder.deleteCharAt(builder.length() - 1); } return builder.toString(); } public static String getSubstringBetween(String input, String start, String end) { int startPos = input.indexOf(start); String result = null; if (startPos != -1) { int endPos = input.indexOf(end, startPos + start.length()); if (endPos != -1) { result = input.substring(startPos + start.length(), endPos); } } return result; } public static String getUnqualifiedClassName(String fqClassName) { int lastDot = fqClassName.lastIndexOf('.'); String result = fqClassName; if (lastDot != -1) { result = fqClassName.substring(lastDot + 1); } return result; } public static String getUnqualifiedMemberName(String memberName) { return getUnqualifiedClassName(memberName); } public static String getPackageName(String fqClassName) { int lastDot = fqClassName.lastIndexOf('.'); String result = S_EMPTY; if (lastDot != -1) { result = fqClassName.substring(0, lastDot); } return result; } public static String padLineNumber(int number, int maxWidth) { return alignRight(Integer.toString(number), maxWidth); } public static String attributeMapToString(Map<String, String> map) { return attributeMapToString(map, C_QUOTE); } public static String attributeMapToString(Map<String, String> map, char quote) { StringBuilder builder = new StringBuilder(); for (Map.Entry<String, String> entry : map.entrySet()) { builder.append(entry.getKey()).append(C_EQUALS).append(quote).append(entry.getValue()).append(quote).append(C_SPACE); } return builder.toString().trim(); } public static Map<String, String> attributeStringToMap(String line) { Map<String, String> result = new HashMap<>(); if (line != null) { int len = line.length(); StringBuilder key = new StringBuilder(); StringBuilder val = new StringBuilder(); boolean inValue = false; for (int i = 0; i < len; i++) { char c = line.charAt(i); switch (c) { case C_SPACE: if (!inValue) { // C_SPACE before new key key.delete(0, key.length()); } else { val.append(C_SPACE); } break; case C_QUOTE: if (inValue) { // finished attr result.put(key.toString(), val.toString()); key.delete(0, key.length()); val.delete(0, val.length()); inValue = false; } else { inValue = true; } break; case C_EQUALS: if (inValue) { val.append(C_EQUALS); } break; default: if (inValue) { val.append(c); } else { key.append(c); } } } } return result; } public static Map<String, String> getLineAttributesDoubleQuote(String line) { Map<String, String> result = new HashMap<>(); if (line != null) { int len = line.length(); StringBuilder key = new StringBuilder(); StringBuilder val = new StringBuilder(); boolean inValue = false; for (int i = 0; i < len; i++) { char c = line.charAt(i); switch (c) { case C_SPACE: if (!inValue) { // C_SPACE before new key key.delete(0, key.length()); } else { val.append(C_SPACE); } break; case C_DOUBLE_QUOTE: if (inValue) { // finished attr result.put(key.toString(), val.toString()); key.delete(0, key.length()); val.delete(0, val.length()); inValue = false; } else { inValue = true; } break; case C_EQUALS: if (inValue) { val.append(C_EQUALS); } break; default: if (inValue) { val.append(c); } else { key.append(c); } } } } return result; } public static String formatThousands(String inValue) { String value = inValue; // see if it can be formatted as a long with commas at thousands try { value = DF_THOUSANDS.format(Long.parseLong(value)); } catch (NumberFormatException nfe) { } return value; } public static String arrayToString(Object[] array) { return listToString(Arrays.asList(array), C_SPACE); } public static String listToString(List<?> list) { return listToString(list, C_SPACE); } public static String listToString(List<?> list, char separator) { StringBuilder builder = new StringBuilder(); if (list != null) { for (Object item : list) { builder.append(item.toString()).append(separator); } if (builder.length() > 0) { builder.deleteCharAt(builder.length() - 1); } } return builder.toString(); } public static String wordWrap(String text, int width) { StringBuilder builder = new StringBuilder(text); int i = 0; while (i + width < builder.length() && (i = builder.lastIndexOf(S_SPACE, i + width)) != -1) { builder.replace(i, i + 1, S_NEWLINE); } return builder.toString(); } public static String getAbbreviatedFQName(String fqClassName) { StringBuilder builder = new StringBuilder(); if (fqClassName != null && fqClassName.length() > 0) { String[] parts = fqClassName.split(S_ESCAPED_DOT); for (int i = 0; i < parts.length - 1; i++) { String part = parts[i]; builder.append(part.charAt(0)).append(C_DOT); } builder.append(parts[parts.length - 1]); } return builder.toString(); } public static List<String> getSortedKeys(Map<String, ?> map) { List<String> attrList = new ArrayList<String>(map.keySet()); Collections.sort(attrList); return attrList; } }