package be.nikiroo.jvcard.resources; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.text.Normalizer; import java.text.Normalizer.Form; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.regex.Pattern; import com.googlecode.lanterna.gui2.LinearLayout.Alignment; public class StringUtils { static private Pattern marks = Pattern .compile("[\\p{InCombiningDiacriticalMarks}\\p{IsLm}\\p{IsSk}]+"); /** * Fix the size of the given {@link String} either with space-padding or by * shortening it. * * @param text * the {@link String} to fix * @param width * the size of the resulting {@link String} if the text fits or * if cut is TRUE * * @return the resulting {@link String} of size size */ static public String padString(String text, int width) { return padString(text, width, true, Alignment.Beginning); } /** * Fix the size of the given {@link String} either with space-padding or by * optionally shortening it. * * @param text * the {@link String} to fix * @param width * the size of the resulting {@link String} if the text fits or * if cut is TRUE * @param cut * cut the {@link String} shorter if needed * @param align * align the {@link String} in this position if we have enough * space * * @return the resulting {@link String} of size size minimum */ static public String padString(String text, int width, boolean cut, Alignment align) { if (width >= 0) { if (text == null) text = ""; int diff = width - text.length(); if (diff < 0) { if (cut) text = text.substring(0, width); } else if (diff > 0) { if (diff < 2 && align != Alignment.End) align = Alignment.Beginning; switch (align) { case Beginning: text = text + new String(new char[diff]).replace('\0', ' '); break; case End: text = new String(new char[diff]).replace('\0', ' ') + text; break; case Center: case Fill: default: int pad1 = (diff) / 2; int pad2 = (diff + 1) / 2; text = new String(new char[pad1]).replace('\0', ' ') + text + new String(new char[pad2]).replace('\0', ' '); break; } } } return text; } /** * Sanitise the given input to make it more Terminal-friendly by removing * combining characters. * * @param input * the input to sanitise * @param allowUnicode * allow Unicode or only allow ASCII Latin characters * * @return the sanitised {@link String} */ static public String sanitize(String input, boolean allowUnicode) { return sanitize(input, allowUnicode, !allowUnicode); } /** * Sanitise the given input to make it more Terminal-friendly by removing * combining characters. * * @param input * the input to sanitise * @param allowUnicode * allow Unicode or only allow ASCII Latin characters * @param removeAllAccents * TRUE to replace all accentuated characters by their non * accentuated counter-parts * * @return the sanitised {@link String} */ static public String sanitize(String input, boolean allowUnicode, boolean removeAllAccents) { if (removeAllAccents) { input = Normalizer.normalize(input, Form.NFKD); input = marks.matcher(input).replaceAll(""); } input = Normalizer.normalize(input, Form.NFKC); if (!allowUnicode) { StringBuilder builder = new StringBuilder(); for (int index = 0; index < input.length(); index++) { char car = input.charAt(index); // displayable chars in ASCII are in the range 32<->255, // except DEL (127) if (car >= 32 && car <= 255 && car != 127) { builder.append(car); } } input = builder.toString(); } return input; } /** * Convert between time in milliseconds to {@link String} in a "static" way * (to exchange data over the wire, for instance). * * @param time * the time in milliseconds * * @return the time as a {@link String} */ static public String fromTime(long time) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); return sdf.format(new Date(time)); } /** * Convert between time as a {@link String} to milliseconds in a "static" * way (to exchange data over the wire, for instance). * * @param time * the time as a {@link String} * * @return the time in milliseconds */ static public long toTime(String display) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); try { return sdf.parse(display).getTime(); } catch (ParseException e) { return -1; } } /** * Return a hash of the given {@link String}. * * @param input * the input data * * @return the hash */ static public String getHash(String input) { try { MessageDigest md = MessageDigest.getInstance("MD5"); md.update(input.getBytes()); byte byteData[] = md.digest(); StringBuffer hexString = new StringBuffer(); for (int i = 0; i < byteData.length; i++) { String hex = Integer.toHexString(0xff & byteData[i]); if (hex.length() == 1) hexString.append('0'); hexString.append(hex); } return hexString.toString(); } catch (NoSuchAlgorithmException e) { // all JVM most probably have an MD5 implementation, but even if // not, returning the input is "correct", if inefficient and // unsecure return input; } } }