/* * Jitsi, the OpenSource Java VoIP and Instant Messaging client. * * Copyright @ 2015 Atlassian Pty Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package net.java.sip.communicator.util; import java.util.*; /** * The StringUtils class is used through this ui implementation for * some special operations with strings. * * @author Yana Stamcheva * @author Lyubomir Marinov * @author Adam Netocny */ public class GuiUtils { private static final Calendar c1 = Calendar.getInstance(); private static final Calendar c2 = Calendar.getInstance(); /** * Number of milliseconds in a second. */ public static final long MILLIS_PER_SECOND = 1000; /** * Number of milliseconds in a standard minute. */ public static final long MILLIS_PER_MINUTE = 60 * MILLIS_PER_SECOND; /** * Number of milliseconds in a standard hour. */ public static final long MILLIS_PER_HOUR = 60 * MILLIS_PER_MINUTE; /** * Number of milliseconds in a standard day. */ public static final long MILLIS_PER_DAY = 24 * MILLIS_PER_HOUR; // These mappings map a character (key) to a specific digit that should // replace it for normalization purposes. Non-European digits that may be // used in phone numbers are mapped to a European equivalent. private static final Map DIGIT_MAPPINGS; /** * Characters and their replacement in created folder names */ private final static String[][] ESCAPE_SEQUENCES = new String[][] { {"&", "&_amp"}, {"/", "&_sl"}, {"\\\\", "&_bs"}, // the char \ {":", "&_co"}, {"\\*", "&_as"}, // the char * {"\\?", "&_qm"}, // the char ? {"\"", "&_pa"}, // the char " {"<", "&_lt"}, {">", "&_gt"}, {"\\|", "&_pp"} // the char | }; static { HashMap digitMap = new HashMap(50); digitMap.put('0', '0'); digitMap.put('\uFF10', '0'); // Fullwidth digit 0 digitMap.put('\u0660', '0'); // Arabic-indic digit 0 digitMap.put('1', '1'); digitMap.put('\uFF11', '1'); // Fullwidth digit 1 digitMap.put('\u0661', '1'); // Arabic-indic digit 1 digitMap.put('2', '2'); digitMap.put('\uFF12', '2'); // Fullwidth digit 2 digitMap.put('\u0662', '2'); // Arabic-indic digit 2 digitMap.put('3', '3'); digitMap.put('\uFF13', '3'); // Fullwidth digit 3 digitMap.put('\u0663', '3'); // Arabic-indic digit 3 digitMap.put('4', '4'); digitMap.put('\uFF14', '4'); // Fullwidth digit 4 digitMap.put('\u0664', '4'); // Arabic-indic digit 4 digitMap.put('5', '5'); digitMap.put('\uFF15', '5'); // Fullwidth digit 5 digitMap.put('\u0665', '5'); // Arabic-indic digit 5 digitMap.put('6', '6'); digitMap.put('\uFF16', '6'); // Fullwidth digit 6 digitMap.put('\u0666', '6'); // Arabic-indic digit 6 digitMap.put('7', '7'); digitMap.put('\uFF17', '7'); // Fullwidth digit 7 digitMap.put('\u0667', '7'); // Arabic-indic digit 7 digitMap.put('8', '8'); digitMap.put('\uFF18', '8'); // Fullwidth digit 8 digitMap.put('\u0668', '8'); // Arabic-indic digit 8 digitMap.put('9', '9'); digitMap.put('\uFF19', '9'); // Fullwidth digit 9 digitMap.put('\u0669', '9'); // Arabic-indic digit 9 DIGIT_MAPPINGS = Collections.unmodifiableMap(digitMap); } /** * Replaces some chars that are special in a regular expression. * @param text The initial text. * @return the formatted text */ public static String replaceSpecialRegExpChars(String text) { return text.replaceAll("([.()^&$*|])", "\\\\$1"); } /** * Counts occurrences of the needle character in the given * text. * @param text the text in which we search * @param needle the character we're looking for * @return the count of occurrences of the needle chat in the * given text */ public static int countOccurrences(String text, char needle) { int count = 0; for (char c : text.toCharArray()) { if (c == needle) ++count; } return count; } /** * Compares the two dates. The comparison is based only on the day, month * and year values. Returns 0 if the two dates are equals, a value < 0 if * the first date is before the second one and > 0 if the first date is after * the second one. * @param date1 the first date to compare * @param date2 the second date to compare with * @return Returns 0 if the two dates are equals, a value < 0 if * the first date is before the second one and > 0 if the first date is after * the second one */ public static int compareDates(Date date1, Date date2) { return date1.compareTo(date2); } /** * Compares the two dates. The comparison is based only on the day, month * and year values. Returns 0 if the two dates are equals, a value < 0 if * the first date is before the second one and > 0 if the first date is after * the second one. * @param date1 the first date to compare * @param date2 the second date to compare with * @return Returns 0 if the two dates are equals, a value < 0 if * the first date is before the second one and > 0 if the first date is after * the second one */ public static int compareDates(long date1, long date2) { return (date1 < date2 ? -1 : (date1 == date2 ? 0 : 1)); } /** * Compares the two dates. The comparison is based only on the day, month * and year values. Returns 0 if the two dates are equals, a value < 0 if * the first date is before the second one and > 0 if the first date is * after the second one. * @param date1 the first date to compare * @param date2 the second date to compare with * @return Returns 0 if the two dates are equals, a value < 0 if * the first date is before the second one and > 0 if the first date is * after the second one */ public static int compareDatesOnly(long date1, long date2) { c1.setTimeInMillis(date1); c2.setTimeInMillis(date2); int day1 = c1.get(Calendar.DAY_OF_MONTH); int month1 = c1.get(Calendar.MONTH); int year1 = c1.get(Calendar.YEAR); int day2 = c2.get(Calendar.DAY_OF_MONTH); int month2 = c2.get(Calendar.MONTH); int year2 = c2.get(Calendar.YEAR); if (year1 < year2) { return -1; } else if (year1 == year2) { if (month1 < month2) return -1; else if (month1 == month2) { if (day1 < day2) return -1; else if (day1 == day2) return 0; else return 1; } else return 1; } else { return 1; } } /** * Compares the two dates. The comparison is based only on the day, month * and year values. Returns 0 if the two dates are equals, a value < 0 if * the first date is before the second one and > 0 if the first date is * after the second one. * @param date1 the first date to compare * @param date2 the second date to compare with * @return Returns 0 if the two dates are equals, a value < 0 if * the first date is before the second one and > 0 if the first date is * after the second one */ public static int compareDatesOnly(Date date1, Date date2) { return compareDatesOnly(date1.getTime(), date2.getTime()); } /** * Formats the given date. The result format is the following: * [Month] [Day], [Year]. For example: Dec 24, 2000. * @param date the date to format * @return the formatted date string */ public static String formatDate(Date date) { return formatDate(date.getTime()); } /** * Formats the given date. The result format is the following: * [Month] [Day], [Year]. For example: Dec 24, 2000. * @param date the date to format * @return the formatted date string */ public static String formatDate(final long date) { StringBuffer strBuf = new StringBuffer(); formatDate(date, strBuf); return strBuf.toString(); } /** * Formats the given date as: Month DD, YYYY and appends it to the given * dateStrBuf string buffer. * @param date the date to format * @param dateStrBuf the StringBuffer, where to append the * formatted date */ public static void formatDate(long date, StringBuffer dateStrBuf) { c1.setTimeInMillis(date); dateStrBuf.append(GuiUtils.processMonth(c1.get(Calendar.MONTH))); dateStrBuf.append(' '); GuiUtils.formatTime(c1.get(Calendar.DAY_OF_MONTH), dateStrBuf); dateStrBuf.append(", "); GuiUtils.formatTime(c1.get(Calendar.YEAR), dateStrBuf); } /** * Formats the given date as: Month DD, YYYY and appends it to the given * dateStrBuf string buffer. * @param date the date to format * @param dateStrBuf the StringBuffer, where to append the * formatted date */ public static void formatDate(Date date, StringBuffer dateStrBuf) { c1.setTime(date); dateStrBuf.append(GuiUtils.processMonth(c1.get(Calendar.MONTH))); dateStrBuf.append(' '); GuiUtils.formatTime(c1.get(Calendar.DAY_OF_MONTH), dateStrBuf); dateStrBuf.append(", "); GuiUtils.formatTime(c1.get(Calendar.YEAR), dateStrBuf); } /** * Formats the time for the given date. The result format is the following: * [Hour]:[Minute]:[Second]. For example: 12:25:30. * @param date the date to format * @return the formatted hour string */ public static String formatTime(Date date) { return formatTime(date.getTime()); } /** * Formats the time for the given date. The result format is the following: * [Hour]:[Minute]:[Second]. For example: 12:25:30. * @param time the date to format * @return the formatted hour string */ public static String formatTime(long time) { c1.setTimeInMillis(time); StringBuffer timeStrBuf = new StringBuffer(); GuiUtils.formatTime(c1.get(Calendar.HOUR_OF_DAY), timeStrBuf); timeStrBuf.append(':'); GuiUtils.formatTime(c1.get(Calendar.MINUTE), timeStrBuf); timeStrBuf.append(':'); GuiUtils.formatTime(c1.get(Calendar.SECOND), timeStrBuf); return timeStrBuf.toString(); } /** * Formats the time period duration for the given start date and end date. * The result format is the following: * [Hour]:[Minute]:[Second]. For example: 12:25:30. * @param startDate the start date * @param endDate the end date * @return the formatted hour string */ public static String formatTime(Date startDate, Date endDate) { return formatTime(startDate.getTime(), endDate.getTime()); } /** * Formats the time period duration for the given start date and end date. * The result format is the following: * [Hour]:[Minute]:[Second]. For example: 12:25:30. * @param start the start date in milliseconds * @param end the end date in milliseconds * @return the formatted hour string */ public static String formatTime(long start, long end) { long duration = end - start; long milPerSec = 1000; long milPerMin = milPerSec*60; long milPerHour = milPerMin*60; long hours = duration / milPerHour; long minutes = ( duration - hours*milPerHour ) / milPerMin; long seconds = ( duration - hours*milPerHour - minutes*milPerMin) / milPerSec; return String.format("%02d:%02d:%02d", hours, minutes, seconds); } /** * Gets the display/human-readable string representation of the month with * the specified zero-based month number. * * @param month the zero-based month number * @return the corresponding month abbreviation */ private static String processMonth(int month) { String monthStringKey; switch (month) { case 0: monthStringKey = "service.gui.JANUARY"; break; case 1: monthStringKey = "service.gui.FEBRUARY"; break; case 2: monthStringKey = "service.gui.MARCH"; break; case 3: monthStringKey = "service.gui.APRIL"; break; case 4: monthStringKey = "service.gui.MAY"; break; case 5: monthStringKey = "service.gui.JUNE"; break; case 6: monthStringKey = "service.gui.JULY"; break; case 7: monthStringKey = "service.gui.AUGUST"; break; case 8: monthStringKey = "service.gui.SEPTEMBER"; break; case 9: monthStringKey = "service.gui.OCTOBER"; break; case 10: monthStringKey = "service.gui.NOVEMBER"; break; case 11: monthStringKey = "service.gui.DECEMBER"; break; default: return ""; } return UtilActivator.getResources().getI18NString(monthStringKey); } /** * Adds a 0 in the beginning of one digit numbers. * * @param time The time parameter could be hours, minutes or seconds. * @param timeStrBuf the StringBuffer to which the formatted * minutes string is to be appended */ private static void formatTime(int time, StringBuffer timeStrBuf) { String timeString = Integer.toString(time); if (timeString.length() < 2) timeStrBuf.append('0'); timeStrBuf.append(timeString); } /** * Formats the given long to X hour, Y min, Z sec. * @param millis the time in milliseconds to format * @return the formatted seconds */ public static String formatSeconds(long millis) { long[] values = new long[4]; values[0] = millis / MILLIS_PER_DAY; values[1] = (millis / MILLIS_PER_HOUR) % 24; values[2] = (millis / MILLIS_PER_MINUTE) % 60; values[3] = (millis / MILLIS_PER_SECOND) % 60; String[] fields = { " d ", " h ", " min ", " sec" }; StringBuffer buf = new StringBuffer(64); boolean valueOutput = false; for (int i = 0; i < 4; i++) { long value = values[i]; if (value == 0) { if (valueOutput) buf.append('0').append(fields[i]); } else { valueOutput = true; buf.append(value).append(fields[i]); } } return buf.toString().trim(); } /** * Replaces the characters that we must escape used for the created * filename. * * @param string the String which is to have its characters escaped * @return a String derived from the specified id by * escaping characters */ public static String escapeFileNameSpecialCharacters(String string) { String resultId = string; for (int j = 0; j < ESCAPE_SEQUENCES.length; j++) { resultId = resultId. replaceAll(ESCAPE_SEQUENCES[j][0], ESCAPE_SEQUENCES[j][1]); } return resultId; } /** * Escapes special HTML characters such as <, >, & and " in * the specified message. * * @param message the message to be processed * @return the processed message with escaped special HTML characters */ public static String escapeHTMLChars(String message) { return message .replace("&", "&") .replace("<", "<") .replace(">", ">") .replace("\"", """) .replace("'", "'") .replace("/", "/"); } }