package models.helpers; import java.math.BigInteger; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Random; import org.apache.commons.lang.StringEscapeUtils; import org.jsoup.Jsoup; import org.jsoup.safety.Whitelist; import org.pegdown.PegDownProcessor; /** * A collection of various small and state-less algorithms for use in the model. */ public class Tools { /** * Digest a password with the SHA-1 hash algorithm. * * @param password * @return the fingerprint of the password */ public static String encrypt(String password) { return digest(password, "SHA-1"); } /** * Calculates a digital fingerprint for a given string with a given hash * algorithm such as MD5 or SHA-1. * * Note: This method exists separatly from encrypt above mainly for testing * purposes, so that the NoSuchAlgorithmException can be tested as well and * 100% code coverage achieved. * * @param string * the string to calculate the fingerprint for * @param hashAlgorithm * the hash algorithm to be used (e.g. MD5 or SHA-1) * @return a hex digest of at most 32 chars for MD5 or 40 chars for SHA-1 * (or <code>null</code> if the desired algorithm isn't available) */ public static String digest(String string, String hashAlgorithm) { try { MessageDigest m = MessageDigest.getInstance(hashAlgorithm); return new BigInteger(1, m.digest(string.getBytes())) .toString(16); } catch (NoSuchAlgorithmException e) { return null; } } /** * Check an email-address to be valid. * * @param email * @return true if the email is valid. */ public static boolean checkEmail(String email) { return email.matches("\\S+@(?:[A-Za-z0-9-]+\\.)+\\w{2,4}"); } public static final String DATE_FORMAT_CH = "dd.MM.yyyy"; public static final String DATE_FORMAT_US = "MM/dd/yyyy"; public static final String DATE_FORMAT_ISO = "yyyy-MM-dd"; /** * Turns the Date object d into a String using the format given in the * constant DATE_FORMAT. */ public static String dateToString(Date d) { if (d != null) return new SimpleDateFormat(DATE_FORMAT_CH).format(d); return null; } /** * Turns the String object s into a Date assuming the format given in the * constant DATE_FORMAT. * * @throws ParseException */ public static Date stringToDate(String s) throws ParseException { if (s.matches("\\d{1,2}\\.\\d{1,2}\\.\\d{4}")) return new SimpleDateFormat(DATE_FORMAT_CH).parse(s); if (s.matches("\\d{1,2}/\\d{1,2}/\\d{4}")) return new SimpleDateFormat(DATE_FORMAT_US).parse(s); if (s.matches("\\d{4}-\\d{1,2}-\\d{1,2}")) return new SimpleDateFormat(DATE_FORMAT_ISO).parse(s); return null; } /** * Takes a String of words with at least 4 characters and counts the * occurrence. Words that occur more than once are treated as important * words. * * @param input * with all the words that contain more than 3 characters * @return keywords with words that occur more than 3 times */ public static List<String> extractImportantWords(String input) { HashMap<String, Integer> keywords = new HashMap(); for (String word : input.toLowerCase().split("\\s+")) { if (word.length() <= 3) { continue; } Integer count = keywords.get(word); if (count == null) { count = 0; } keywords.put(word, count + 1); } HashMap<String, Integer> filtered = new HashMap(); for (String word : keywords.keySet()) { Integer count = keywords.get(word); if (count > 1 && !StopWords.get().contains(word)) { filtered.put(word, -count); } } List<String> sorted = Mapper.sortByValue(filtered); if (sorted.size() > 5) { sorted = sorted.subList(0, 5); } Collections.sort(sorted); return sorted; } /** * Sorts a list of entries and segments them into parts according to a * certain number of entries per part. * * @param entries * the list to be segmented * @param entriesPerPage * the amount of entries on one page * @param pageNumber * the number of the requested page * * * @return a list of the entries on the given page number. * */ public static List paginate(List entries, int entriesPerPage, int index) { int limit = entries.size(); int upperBound = ((index + 1) * entriesPerPage); if (upperBound <= limit) return entries.subList(index * entriesPerPage, upperBound); if (index * entriesPerPage <= limit) return entries.subList(index * entriesPerPage, limit); return new ArrayList(); } public static int determineMaximumIndex(List entries, int entriesPerPage) { return (entries.size() - 1) / entriesPerPage; } /** * Convert Markdown to HTML content (in an amazingly unoptimized way) * * @param content * some Markdown content * @return that content in plain and sanitized HTML (XSS safe!) */ public static String markdownToHtml(String content) { // optimization for the XML importer: don't use the slow // Markdown processor for content that's already HTML if (content.startsWith("<h3>")) return Jsoup.clean(content, Whitelist.basic()); return Jsoup.clean(new PegDownProcessor().markdownToHtml(content), Whitelist.basic()); } /** * Strip all HTML tags. * * @param content * the HTML content to strip the tags from * @return the string */ public static String htmlToText(String content) { return StringEscapeUtils.unescapeHtml(Jsoup.clean(content, Whitelist .none())); } /** * Generate a String with random chars * * @param length * of the String * @return the string */ public static String randomStringGenerator(int length) { char[] letters = new char[26]; char[] buffer = new char[length]; Random random = new Random(); for (int i = 0; i < 26; i++) { letters[i] = (char) ('a' + i); } for (int i = 0; i < length; i++) { buffer[i] = letters[random.nextInt(letters.length)]; } return new String(buffer); } }