001package io.ebean.util; 002 003import java.util.HashMap; 004import java.util.Map; 005import java.util.regex.Pattern; 006 007/** 008 * Utility String class that supports String manipulation functions. 009 */ 010public class StringHelper { 011 012 private static final Pattern SPLIT_NAMES = Pattern.compile("[\\s,;]+"); 013 014 private static final String[] EMPTY_STRING_ARRAY = new String[0]; 015 016 /** 017 * Return true if the value is null or an empty string. 018 */ 019 public static boolean isNull(String value) { 020 return value == null || value.trim().isEmpty(); 021 } 022 023 /** 024 * Parses out a list of Name Value pairs that are delimited together. Will 025 * always return a StringMap. If allNameValuePairs is null, or no name values 026 * can be parsed out an empty StringMap is returned. 027 * 028 * @param source the entire string to be parsed. 029 * @param listDelimiter (typically ';') the delimited between the list 030 * @param nameValueSeparator (typically '=') the separator between the name and value 031 */ 032 public static Map<String, String> delimitedToMap(String source, String listDelimiter, String nameValueSeparator) { 033 Map<String, String> params = new HashMap<>(); 034 if (source == null || source.isEmpty()) { 035 return params; 036 } 037 // trim off any leading listDelimiter... 038 source = trimFront(source, listDelimiter); 039 return delimitedToMap(params, source, listDelimiter, nameValueSeparator); 040 } 041 042 /** 043 * Trims off recurring strings from the front of a string. 044 * 045 * @param source the source string 046 * @param trim the string to trim off the front 047 */ 048 private static String trimFront(String source, String trim) { 049 while (true) { 050 if (source.indexOf(trim) == 0) { 051 source = source.substring(trim.length()); 052 } else { 053 return source; 054 } 055 } 056 } 057 058 /** 059 * Recursively pulls out the key value pairs from a raw string. 060 */ 061 private static Map<String, String> delimitedToMap(Map<String, String> map, String source, String listDelimiter, String nameValueSeparator) { 062 int pos = 0; 063 while (true) { 064 if (pos >= source.length()) { 065 return map; 066 } 067 int equalsPos = source.indexOf(nameValueSeparator, pos); 068 int delimPos = source.indexOf(listDelimiter, pos); 069 if (delimPos == -1) { 070 delimPos = source.length(); 071 } 072 if (equalsPos == -1) { 073 return map; 074 } 075 if (delimPos == (equalsPos + 1)) { 076 pos = delimPos + 1; 077 continue; 078 } 079 if (equalsPos > delimPos) { 080 // there is a key without a value? 081 String key = source.substring(pos, delimPos); 082 key = key.trim(); 083 if (!key.isEmpty()) { 084 map.put(key, null); 085 } 086 pos = delimPos + 1; 087 continue; 088 } 089 String key = source.substring(pos, equalsPos); 090 String value = source.substring(equalsPos + 1, delimPos); 091 map.put(key.trim(), value); 092 pos = delimPos + 1; 093 } 094 } 095 096 /** 097 * This method takes a String and will replace all occurrences of the match 098 * String with that of the replace String. 099 * 100 * @param source the source string 101 * @param match the string used to find a match 102 * @param replace the string used to replace match with 103 * @return the source string after the search and replace 104 */ 105 public static String replace(String source, String match, String replace) { 106 if (source == null) { 107 return null; 108 } 109 if (replace == null) { 110 return source; 111 } 112 return source.replace(match, replace); 113 } 114 115 /** 116 * Return new line and carriage return with space. 117 */ 118 public static String removeNewLines(String source) { 119 source = source.replace('\n', ' '); 120 return source.replace('\r', ' '); 121 } 122 123 /** 124 * Splits at any whitespace "," or ";" and trims the result. 125 * It does not return empty entries. 126 */ 127 public static String[] splitNames(String names) { 128 if (names == null || names.isEmpty()) { 129 return EMPTY_STRING_ARRAY; 130 } 131 String[] result = SPLIT_NAMES.split(names); 132 if (result.length == 0) { 133 return EMPTY_STRING_ARRAY; 134 } 135 if ("".equals(result[0])) { // input string starts with whitespace 136 if (result.length == 1) { // input string contains only whitespace 137 return EMPTY_STRING_ARRAY; 138 } else { 139 String[] ret = new String[result.length-1]; // remove first entry 140 System.arraycopy(result, 1, ret, 0, ret.length); 141 return ret; 142 } 143 } else { 144 return result; 145 } 146 } 147}