001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019 020 package org.apache.fulcrum.yaafi.framework.util; 021 022 import java.util.Map; 023 024 025 /** 026 * A subset of the utilities available in commons-lang-2.1 StringUtils. 027 * 028 * @author <a href="mailto:siegfried.goeschl@it20one.at">Siegfried Goeschl</a> 029 */ 030 public class StringUtils 031 { 032 // Replacing 033 //----------------------------------------------------------------------- 034 /** 035 * <p>Replaces a String with another String inside a larger String, once.</p> 036 * 037 * <p>A <code>null</code> reference passed to this method is a no-op.</p> 038 * 039 * <pre> 040 * StringUtils.replaceOnce(null, *, *) = null 041 * StringUtils.replaceOnce("", *, *) = "" 042 * StringUtils.replaceOnce("aba", null, null) = "aba" 043 * StringUtils.replaceOnce("aba", null, null) = "aba" 044 * StringUtils.replaceOnce("aba", "a", null) = "aba" 045 * StringUtils.replaceOnce("aba", "a", "") = "aba" 046 * StringUtils.replaceOnce("aba", "a", "z") = "zba" 047 * </pre> 048 * 049 * @see #replace(String text, String repl, String with, int max) 050 * @param text text to search and replace in, may be null 051 * @param repl the String to search for, may be null 052 * @param with the String to replace with, may be null 053 * @return the text with any replacements processed, 054 * <code>null</code> if null String input 055 */ 056 public static String replaceOnce(String text, String repl, String with) { 057 return replace(text, repl, with, 1); 058 } 059 060 /** 061 * <p>Replaces all occurrences of a String within another String.</p> 062 * 063 * <p>A <code>null</code> reference passed to this method is a no-op.</p> 064 * 065 * <pre> 066 * StringUtils.replace(null, *, *) = null 067 * StringUtils.replace("", *, *) = "" 068 * StringUtils.replace("aba", null, null) = "aba" 069 * StringUtils.replace("aba", null, null) = "aba" 070 * StringUtils.replace("aba", "a", null) = "aba" 071 * StringUtils.replace("aba", "a", "") = "aba" 072 * StringUtils.replace("aba", "a", "z") = "zbz" 073 * </pre> 074 * 075 * @see #replace(String text, String repl, String with, int max) 076 * @param text text to search and replace in, may be null 077 * @param repl the String to search for, may be null 078 * @param with the String to replace with, may be null 079 * @return the text with any replacements processed, 080 * <code>null</code> if null String input 081 */ 082 public static String replace(String text, String repl, String with) { 083 return replace(text, repl, with, -1); 084 } 085 086 /** 087 * <p>Replaces a String with another String inside a larger String, 088 * for the first <code>max</code> values of the search String.</p> 089 * 090 * <p>A <code>null</code> reference passed to this method is a no-op.</p> 091 * 092 * <pre> 093 * StringUtils.replace(null, *, *, *) = null 094 * StringUtils.replace("", *, *, *) = "" 095 * StringUtils.replace("abaa", null, null, 1) = "abaa" 096 * StringUtils.replace("abaa", null, null, 1) = "abaa" 097 * StringUtils.replace("abaa", "a", null, 1) = "abaa" 098 * StringUtils.replace("abaa", "a", "", 1) = "abaa" 099 * StringUtils.replace("abaa", "a", "z", 0) = "abaa" 100 * StringUtils.replace("abaa", "a", "z", 1) = "zbaa" 101 * StringUtils.replace("abaa", "a", "z", 2) = "zbza" 102 * StringUtils.replace("abaa", "a", "z", -1) = "zbzz" 103 * </pre> 104 * 105 * @param text text to search and replace in, may be null 106 * @param repl the String to search for, may be null 107 * @param with the String to replace with, may be null 108 * @param max maximum number of values to replace, or <code>-1</code> if no maximum 109 * @return the text with any replacements processed, 110 * <code>null</code> if null String input 111 */ 112 public static String replace(String text, String repl, String with, int max) { 113 if (text == null || repl == null || with == null || repl.length() == 0 || max == 0) { 114 return text; 115 } 116 117 StringBuffer buf = new StringBuffer(text.length()); 118 int start = 0, end = 0; 119 while ((end = text.indexOf(repl, start)) != -1) { 120 buf.append(text.substring(start, end)).append(with); 121 start = end + repl.length(); 122 123 if (--max == 0) { 124 break; 125 } 126 } 127 buf.append(text.substring(start)); 128 return buf.toString(); 129 } 130 131 // Replace, character based 132 //----------------------------------------------------------------------- 133 /** 134 * <p>Replaces all occurrences of a character in a String with another. 135 * This is a null-safe version of {@link String#replace(char, char)}.</p> 136 * 137 * <p>A <code>null</code> string input returns <code>null</code>. 138 * An empty ("") string input returns an empty string.</p> 139 * 140 * <pre> 141 * StringUtils.replaceChars(null, *, *) = null 142 * StringUtils.replaceChars("", *, *) = "" 143 * StringUtils.replaceChars("abcba", 'b', 'y') = "aycya" 144 * StringUtils.replaceChars("abcba", 'z', 'y') = "abcba" 145 * </pre> 146 * 147 * @param str String to replace characters in, may be null 148 * @param searchChar the character to search for, may be null 149 * @param replaceChar the character to replace, may be null 150 * @return modified String, <code>null</code> if null string input 151 * @since 2.0 152 */ 153 public static String replaceChars(String str, char searchChar, 154 char replaceChar) 155 { 156 if (str == null) 157 { 158 return null; 159 } 160 return str.replace( searchChar, replaceChar ); 161 } 162 163 /** 164 * <p>Replaces multiple characters in a String in one go. 165 * This method can also be used to delete characters.</p> 166 * 167 * <p>For example:<br /> 168 * <code>replaceChars("hello", "ho", "jy") = jelly</code>.</p> 169 * 170 * <p>A <code>null</code> string input returns <code>null</code>. 171 * An empty ("") string input returns an empty string. 172 * A null or empty set of search characters returns the input string.</p> 173 * 174 * <p>The length of the search characters should normally equal the length 175 * of the replace characters. 176 * If the search characters is longer, then the extra search characters 177 * are deleted. 178 * If the search characters is shorter, then the extra replace characters 179 * are ignored.</p> 180 * 181 * <pre> 182 * StringUtils.replaceChars(null, *, *) = null 183 * StringUtils.replaceChars("", *, *) = "" 184 * StringUtils.replaceChars("abc", null, *) = "abc" 185 * StringUtils.replaceChars("abc", "", *) = "abc" 186 * StringUtils.replaceChars("abc", "b", null) = "ac" 187 * StringUtils.replaceChars("abc", "b", "") = "ac" 188 * StringUtils.replaceChars("abcba", "bc", "yz") = "ayzya" 189 * StringUtils.replaceChars("abcba", "bc", "y") = "ayya" 190 * StringUtils.replaceChars("abcba", "bc", "yzx") = "ayzya" 191 * </pre> 192 * 193 * @param str String to replace characters in, may be null 194 * @param searchChars a set of characters to search for, may be null 195 * @param replaceChars a set of characters to replace, may be null 196 * @return modified String, <code>null</code> if null string input 197 * @since 2.0 198 */ 199 public static String replaceChars(String str, String searchChars, 200 String replaceChars) 201 { 202 if (isEmpty( str ) || isEmpty( searchChars )) 203 { 204 return str; 205 } 206 if (replaceChars == null) 207 { 208 replaceChars = ""; 209 } 210 boolean modified = false; 211 StringBuffer buf = new StringBuffer( str.length() ); 212 for (int i = 0; i < str.length(); i++) 213 { 214 char ch = str.charAt( i ); 215 int index = searchChars.indexOf( ch ); 216 if (index >= 0) 217 { 218 modified = true; 219 if (index < replaceChars.length()) 220 { 221 buf.append( replaceChars.charAt( index ) ); 222 } 223 } 224 else 225 { 226 buf.append( ch ); 227 } 228 } 229 if (modified) 230 { 231 return buf.toString(); 232 } 233 else 234 { 235 return str; 236 } 237 } 238 239 /** 240 * <p>Checks if a String is empty ("") or null.</p> 241 * 242 * <pre> 243 * StringUtils.isEmpty(null) = true 244 * StringUtils.isEmpty("") = true 245 * StringUtils.isEmpty(" ") = false 246 * StringUtils.isEmpty("bob") = false 247 * StringUtils.isEmpty(" bob ") = false 248 * </pre> 249 * 250 * <p>NOTE: This method changed in Lang version 2.0. 251 * It no longer trims the String. 252 * That functionality is available in isBlank().</p> 253 * 254 * @param str the String to check, may be null 255 * @return <code>true</code> if the String is empty or null 256 */ 257 public static boolean isEmpty(String str) 258 { 259 return str == null || str.length() == 0; 260 } 261 262 /** 263 * Perform a series of substitutions. The substitions 264 * are performed by replacing ${variable} in the target 265 * string with the value of provided by the key "variable" 266 * in the provided hashtable. 267 * 268 * @param argStr target string 269 * @param vars name/value pairs used for substitution 270 * @param isLenient ignore failures 271 * @return String target string with replacements. 272 */ 273 public static StringBuffer stringSubstitution(String argStr, Map vars, boolean isLenient) 274 { 275 StringBuffer argBuf = new StringBuffer(); 276 int argStrLength = argStr.length(); 277 278 for (int cIdx = 0 ; cIdx < argStrLength;) 279 { 280 char ch = argStr.charAt(cIdx); 281 char del = ' '; 282 283 switch (ch) 284 { 285 case '$': 286 StringBuffer nameBuf = new StringBuffer(); 287 del = argStr.charAt(cIdx+1); 288 if( del == '{') 289 { 290 cIdx++; 291 292 for (++cIdx ; cIdx < argStr.length(); ++cIdx) 293 { 294 ch = argStr.charAt(cIdx); 295 if (ch != '}') 296 nameBuf.append(ch); 297 else 298 break; 299 } 300 301 if (nameBuf.length() > 0) 302 { 303 Object value = vars.get(nameBuf.toString()); 304 305 if (value != null) 306 { 307 argBuf.append(value.toString()); 308 } 309 else 310 { 311 if (!isLenient) 312 { 313 throw new RuntimeException("No value found for : " + nameBuf ); 314 } 315 } 316 317 del = argStr.charAt(cIdx); 318 319 if( del != '}') 320 { 321 throw new RuntimeException("Delimineter not found for : " + nameBuf ); 322 } 323 } 324 325 cIdx++; 326 } 327 else 328 { 329 argBuf.append(ch); 330 ++cIdx; 331 } 332 333 break; 334 335 default: 336 argBuf.append(ch); 337 ++cIdx; 338 break; 339 } 340 } 341 342 return argBuf; 343 } 344 }