All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.crazyyak.dev.common.StringUtils Maven / Gradle / Ivy

/*
 * Copyright 2012 Jacob D Parr
 *
 * 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 org.crazyyak.dev.common;

import java.io.UnsupportedEncodingException;
import java.net.*;
import java.util.*;
import org.crazyyak.dev.common.exceptions.ExceptionUtils;
import org.joda.time.LocalDate;

import static java.lang.String.format;

public class StringUtils {
  
  public static String UTF_8 = "UTF-8";
  public static Map htmlMap = htmlMap();
  
  private StringUtils() {
  }

  public static int countOccurrencesOf(String str, String sub) {
    if (str == null || sub == null || str.length() == 0 || sub.length() == 0) {
      return 0;
    }
    int count = 0;
    int pos = 0;
    int idx;
    while ((idx = str.indexOf(sub, pos)) != -1) {
      ++count;
      pos = idx + sub.length();
    }
    return count;
  }

  /** Helper method to determine if a string is null or zero-length */
  public static boolean isBlank(Object value) {
    return (value == null || value.toString().isEmpty());
  }
  
  /** Helper method to determine if any one of the specified values is null or zero-length */
  public static boolean isNotBlank(Object...values) {
    if (values == null) {
      return false;
    }
    for (Object value : values) {
      boolean blank = (value == null || value.toString().isEmpty());
      if (blank) return false;
    }
    return true;
  }
  
  /** Helper method to help determine if a string is null contains only whitespace. */
  public static boolean isWhitespace(Object value) {
    return (value == null || value.toString().trim().isEmpty());
  }

  public static String escapeHtml(String data) {
    if (data == null) {
      return null;
    }

    // A list of characters that do not need to be escaped.
    List acceptable = new ArrayList();
    for (char c = 'a'; c <= 'z'; c++) acceptable.add(c);
    for (char c = 'A'; c <= 'Z'; c++) acceptable.add(c);
    for (char c = '0'; c <= '9'; c++) acceptable.add(c);
    acceptable.addAll(Arrays.asList('-', '.', ',', '_'));

    StringBuilder builder = new StringBuilder();
    for ( int i = 0; i < data.length(); i++ ) {
      char c = data.charAt( i );
      if (acceptable.contains(c)) {
        builder.append(c);
      } else {
        builder.append("&#");
        builder.append(Integer.valueOf(c));
        builder.append(";");
      }
    }
    return builder.toString();
  }

  public static List tokenize(String data, char delimiter) {
    List retVal = new ArrayList();
    StringTokenizer tokenizer = new StringTokenizer(data, delimiter+"");
    while (tokenizer.hasMoreTokens()) {
      retVal.add(tokenizer.nextToken());
    }
    return retVal;
  }

  public static String concat(String delim, String...segments) {
    ExceptionUtils.assertNotNull(segments, "segments");
    return concat(delim, Arrays.asList(segments));
  }
  
  public static String concat(String delimiter, List segments) {
    ExceptionUtils.assertNotNull(delimiter, "delimiter");
    ExceptionUtils.assertNotNull(segments, "segments");
    
    StringBuilder builder = new StringBuilder();
    for (Object segment : segments) {
      if (builder.length() > 0) {
        builder.append(delimiter);
      }
      builder.append(segment);
    }
    
    return builder.toString();
  }

  public static String decodeUrl(String url) {
    if (url == null) {
      return null;
    }
    try {
      return URLDecoder.decode(url, UTF_8);
    } catch (UnsupportedEncodingException e) {
      throw new RuntimeException(e);
    }
  }

  public static String encodeUrl(String url) {
    if (url == null) {
      return null;
    }
    try {
      return URLEncoder.encode(url, UTF_8);
    } catch (UnsupportedEncodingException e) {
      throw new RuntimeException(e);
    }
  }

  public static LocalDate parseDate(final String date) {
    String test = date;
    if (test == null) return null;
    
    try { return new LocalDate(test);
    } catch (IllegalArgumentException ignored){}
    
    test = test.replace('/', '-');
    try { return new LocalDate(test);
    } catch (IllegalArgumentException ignored){}
   
    String[] parts = test.split("-");
    if (parts.length == 3 && parts[2].length() == 4) {
      String year = parts[2];
      
      String month = parts[0];
      if (month.length() < 2) month = "0"+month;
      
      String day = parts[1];
      if (day.length() < 2) day = "0"+day;
      
      try { return new LocalDate(format("%s-%s-%s", year, month, day));
      } catch (IllegalArgumentException ignored){}
    }
    
    String msg = format("Unable to parse the value \"%s\" into a valid %s.", date, LocalDate.class.getName());
    throw new IllegalArgumentException(msg);
  }

  public static String getNth(int sequence) {
    if (sequence >= 4 && sequence <= 20) {
      return sequence+"th";
    } else {
      String sv = String.valueOf(sequence);
      char last = sv.charAt(sv.length()-1);
      if (last == '1') {
        return sequence+"st";
      } else if (last == '2') {
        return sequence+"nd";
      } else if (last == '3') {
        return sequence+"rd";
      } else {
        return sequence+"th";
      }
    }
  }


  public static String toDelineatedString(String delineator, Object...values) {
    return toDelineatedString(delineator, delineator, Arrays.asList(values));
  }

  public static String toDelineatedString(String delineator, Collection objects) {
    return toDelineatedString(delineator, delineator, objects);
  }

  public static String toDelineatedString(String delineator, String lastDelineator, Object... objectsArray) {
    return toDelineatedString(delineator, lastDelineator, Arrays.asList(objectsArray));
  }

  public static String toDelineatedString(String delineator, String lastDelineator, Collection objectsCollections) {
    List objects = new ArrayList(objectsCollections);

    StringBuilder builder = new StringBuilder();

    for (int i = 0; i < objects.size(); i++) {
      String id = objects.get(i).toString();

      if (i > 0 && i == objects.size() - 1) {
        builder.append(lastDelineator);
      } else if (i > 0) {
        builder.append(delineator);
      }

      builder.append(id);
    }
    return builder.toString();
  }

  /** 
   * Safely converts an object to it's string value without 
   * a "null value check". If the value is null, null is returned. 
   */
  public static String toString(Object object) {
    return (object == null) ? null : object.toString();
  }
  
  public static String getTagContents(final String xml, final String tagName, final int offset) {
    if (xml == null) {
      return null;
    }
    
    String begTag = String.format("<%s ", tagName);
    
    int posA = xml.indexOf(begTag, offset);
    if (posA < 0) {
      begTag = String.format("<%s>", tagName);
      posA = xml.indexOf(begTag, offset);
      if (posA < 0) {
        return null;
      }
    }
    
    int posB = xml.indexOf(">", posA+1);
    if (posB < 0) {
      return null;
    }
    
    if ('/' == xml.charAt(posB-1)) {
      // we have an empty tag.
      return null;
    }
    
    posA = posB+1;
    String endTag = String.format("", tagName);
    posB = xml.indexOf(endTag, posA);
    if (posB < 0) {
      return null;
    }
    
    String text = xml.substring(posA, posB);
    return text;
  }

  public static String encode_ISO_8859_1(String text) {
    if (text == null) return null;

    StringBuilder builder = new StringBuilder();
    
    for (char chr : text.toCharArray()) {
      String txt = htmlMap.get((int)chr);
      if (txt == null) {
        builder.append(chr);
      } else {
        builder.append("&");
        builder.append(txt);
        builder.append(";");
      }
    }
    
    return builder.toString();
  }

  private static Map htmlMap() {
    
    Map map = new HashMap();
    
    map.put(160, "nbsp");
    map.put(161, "iexcl");
    map.put(162, "cent");
    map.put(163, "pound");
    map.put(164, "curren");
    map.put(165, "yen");
    map.put(166, "brvbar");
    map.put(167, "sect");
    map.put(168, "uml");
    map.put(169, "copy");
    map.put(170, "ordf");
    map.put(171, "laquo");
    map.put(172, "not");
    map.put(173, "shy");
    map.put(174, "reg");
    map.put(175, "macr");
    map.put(176, "deg");
    map.put(177, "plusmn");
    map.put(178, "sup2");
    map.put(179, "sup3");
    map.put(180, "acute");
    map.put(181, "micro");
    map.put(182, "para");
    map.put(183, "middot");
    map.put(184, "cedil");
    map.put(185, "sup1");
    map.put(186, "ordm");
    map.put(187, "raquo");
    map.put(188, "frac14");
    map.put(189, "frac12");
    map.put(190, "frac34");
    map.put(191, "iquest");
    map.put(192, "Agrave");
    map.put(193, "Aacute");
    map.put(194, "Acirc");
    map.put(195, "Atilde");
    map.put(196, "Auml");
    map.put(197, "Aring");
    map.put(198, "AElig");
    map.put(199, "Ccedil");
    map.put(200, "Egrave");
    map.put(201, "Eacute");
    map.put(202, "Ecirc");
    map.put(203, "Euml");
    map.put(204, "Igrave");
    map.put(205, "Iacute");
    map.put(206, "Icirc");
    map.put(207, "Iuml");
    map.put(208, "ETH");
    map.put(209, "Ntilde");
    map.put(210, "Ograve");
    map.put(211, "Oacute");
    map.put(212, "Ocirc");
    map.put(213, "Otilde");
    map.put(214, "Ouml");
    map.put(215, "times");
    map.put(216, "Oslash");
    map.put(217, "Ugrave");
    map.put(218, "Uacute");
    map.put(219, "Ucirc");
    map.put(220, "Uuml");
    map.put(221, "Yacute");
    map.put(222, "THORN");
    map.put(223, "szlig");
    map.put(224, "agrave");
    map.put(225, "aacute");
    map.put(226, "acirc");
    map.put(227, "atilde");
    map.put(228, "auml");
    map.put(229, "aring");
    map.put(230, "aelig");
    map.put(231, "ccedil");
    map.put(232, "egrave");
    map.put(233, "eacute");
    map.put(234, "ecirc");
    map.put(235, "euml");
    map.put(236, "igrave");
    map.put(237, "iacute");
    map.put(238, "icirc");
    map.put(239, "iuml");
    map.put(240, "eth");
    map.put(241, "ntilde");
    map.put(242, "ograve");
    map.put(243, "oacute");
    map.put(244, "ocirc");
    map.put(245, "otilde");
    map.put(246, "ouml");
    map.put(247, "divide");
    map.put(248, "oslash");
    map.put(249, "ugrave");
    map.put(250, "uacute");
    map.put(251, "ucirc");
    map.put(252, "uuml");
    map.put(253, "yacute");
    map.put(254, "thorn");
    map.put(255, "yuml");

    return Collections.unmodifiableMap(map);
  }

  public static String trimLeft(String value, int length, String ellipsis) {

    String text = (value == null) ? "" : value;
    if (ellipsis == null) ellipsis = "";

    if (text.length() > length) {
      int pos = text.length() - length + ellipsis.length();
      text = text.substring(Math.min(pos, text.length()));
      text = ellipsis + text;

      if (text.length() > length) {
        text = text.substring(0, length);
      }
    }

    return text;
  }

  public static String padLeft(String text, int length, char chr) {

    int size = (text == null) ? 0 : text.length();
    StringBuilder builder = new StringBuilder(text == null ? "" : text);

    for (int i = size; i < length; i++) {
      builder.insert(0, chr);
    }

    return builder.toString();
  }

  public static String fixedLeft(String value, int i, char chr, String ellipsis) {
    String text = (value == null) ? "" : value;
    text = StringUtils.trimLeft(text, i, ellipsis);
    text = StringUtils.padLeft(text, i, chr);
    return text;
  }

  public static String trimRight(String value, int length, String ellipsis) {

    String text = (value == null) ? "" : value;
    if (ellipsis == null) ellipsis = "";

    if (ellipsis.length() > length) {
      return ellipsis.substring(0, length);
    }

    if (text.length() > length) {
      text = text.substring(0, length- ellipsis.length());
      text += ellipsis;
    }

    return text;
  }

  public static String padRight(String text, int length, char chr) {

    int size = (text == null) ? 0 : text.length();
    StringBuilder builder = new StringBuilder(text == null ? "" : text);

    for (int i = size; i < length; i++) {
      builder.append(chr);
    }

    return builder.toString();
  }

  public static String fixedRight(String value, int i, char chr, String ellipsis) {
    String text = (value == null) ? "" : value;
    text = StringUtils.trimRight(text, i, ellipsis);
    text = StringUtils.padRight(text, i, chr);
    return text;
  }

  public static String substring(String text, int beginIndex, int endIndex) {
    if (text == null) {
      return null;
    }
    endIndex = Math.min(endIndex, text.length());
    return text.substring(beginIndex, endIndex);
  }

  public static int length(String message) {
    return (message == null) ? 0 : message.length();
  }

  public static String removeZeroDecimal(String value) {
    while (value.endsWith("0")) {
      value = value.substring(0, value.length()-1);
    }
    while (value.endsWith(".")) {
      value = value.substring(0, value.length()-1);
    }
    return value;
  }

  /** Used to ensure that an empty string is converted to null. */
  public static String emptyToNull(String value) {
    if (StringUtils.isBlank(value)) {
      return null;
    } else {
      return value;
    }
  }

  /** Used to ensure that an empty string is converted to null. */
  public static String blankToNull(String value) {
    if (StringUtils.isBlank(value)) {
      return null;
    } else {
      return value.trim().isEmpty() ? null : value;
    }
  }

  public static String sanitizePhoneNumber(String phoneNumber) {
    phoneNumber = blankToNull(phoneNumber);
    if (phoneNumber == null) return null;

    phoneNumber = phoneNumber.replaceAll(" ", "");
    phoneNumber = phoneNumber.replaceAll("-", "");
    phoneNumber = phoneNumber.replaceAll("\\.", "");
    phoneNumber = phoneNumber.replaceAll("\\(", "");
    phoneNumber = phoneNumber.replaceAll("\\)", "");

    return phoneNumber;
  }

  public static String appendQueryParam(String url, Object key, Object value) {
    if (url == null) return null;

    int pos = url.indexOf("?");

    if (pos < 0) {
      // It doesn't exist, go ahead and add it.
      return url + "?" + key + "=" + value;

    } else if (pos == url.length()-1 || url.endsWith("&")) {
      // It's at the end, just add the query.
      return url + key + "=" + value;

    } else {
      return url + "&" + key + "=" + value;

    }
  }

  public static String removeLineSeparators(String str) {
    return str.replaceAll("(\\r)?\\n", "");
  }

  public static String replaceLineSeparators(String str, String with) {
    return str.replaceAll("(\\r)?\\n", with);
  }
}