1 | /* This file is part of the project "Hilbert II" - http://www.qedeq.org |
2 | * |
3 | * Copyright 2000-2014, Michael Meyling <mime@qedeq.org>. |
4 | * |
5 | * "Hilbert II" is free software; you can redistribute |
6 | * it and/or modify it under the terms of the GNU General Public |
7 | * License as published by the Free Software Foundation; either |
8 | * version 2 of the License, or (at your option) any later version. |
9 | * |
10 | * This program is distributed in the hope that it will be useful, |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | * GNU General Public License for more details. |
14 | */ |
15 | |
16 | package org.qedeq.base.utility; |
17 | |
18 | import java.io.BufferedReader; |
19 | import java.io.ByteArrayOutputStream; |
20 | import java.io.IOException; |
21 | import java.io.StringReader; |
22 | import java.io.UnsupportedEncodingException; |
23 | import java.util.ArrayList; |
24 | import java.util.Iterator; |
25 | import java.util.List; |
26 | import java.util.Locale; |
27 | import java.util.Map; |
28 | import java.util.Properties; |
29 | import java.util.Set; |
30 | |
31 | import org.apache.commons.lang.ArrayUtils; |
32 | import org.apache.commons.lang.StringEscapeUtils; |
33 | import org.apache.commons.lang.SystemUtils; |
34 | |
35 | |
36 | |
37 | /** |
38 | * A collection of useful static methods for strings. |
39 | * |
40 | * LATER mime 20070101: use StringBuilder instead of StringBuffer if working under JDK 1.5 |
41 | * |
42 | * @author Michael Meyling |
43 | */ |
44 | public final class StringUtility { |
45 | |
46 | /** For trimming with zeros. */ |
47 | static final String FORMATED_ZERO = "00000000000000000000"; |
48 | |
49 | /** For trimming with spaces. */ |
50 | static final String FORMATED_SPACES = " "; |
51 | |
52 | /** |
53 | * Constructor, should never be called. |
54 | */ |
55 | private StringUtility() { |
56 | // don't call me |
57 | } |
58 | |
59 | /** |
60 | * Replaces all occurrences of <code>search</code> in <code>text</code> |
61 | * by <code>replace</code> and returns the result. |
62 | * |
63 | * @param text text to work on, can be <code>null</code> |
64 | * @param search replace this text by <code>replace</code>, can be <code>null</code> |
65 | * @param replace replacement for <code>search</code>, can be <code>null</code> |
66 | * @return resulting string (is never <code>null</code>) |
67 | */ |
68 | public static String replace(final String text, |
69 | final String search, final String replace) { |
70 | |
71 | if (text == null) { |
72 | return ""; |
73 | } |
74 | final int len = search != null ? search.length() : 0; |
75 | if (len == 0) { |
76 | return text; |
77 | } |
78 | final StringBuffer result = new StringBuffer(); |
79 | int pos1 = 0; |
80 | int pos2; |
81 | while (0 <= (pos2 = text.indexOf(search, pos1))) { |
82 | result.append(text.substring(pos1, pos2)); |
83 | if (replace != null) { |
84 | result.append(replace); |
85 | } |
86 | pos1 = pos2 + len; |
87 | } |
88 | if (pos1 < text.length()) { |
89 | result.append(text.substring(pos1)); |
90 | } |
91 | return result.toString(); |
92 | } |
93 | |
94 | /** |
95 | * Replaces all occurrences of <code>search</code> in <code>text</code> |
96 | * by <code>replace</code>. |
97 | * |
98 | * @param text Text to work on. Must not be <code>null</code>. |
99 | * @param search replace this text by <code>replace</code>. Can be <code>null</code>. |
100 | * @param replace replacement for <code>search</code>. Can be <code>null</code>. |
101 | * @throws NullPointerException <code>text</code> is <code>null</code>. |
102 | */ |
103 | public static void replace(final StringBuffer text, |
104 | final String search, final String replace) { |
105 | if (search == null || search.length() <= 0) { |
106 | return; |
107 | } |
108 | final StringBuffer result = new StringBuffer(text.length() + 16); |
109 | int pos1 = 0; |
110 | int pos2; |
111 | final int len = search.length(); |
112 | while (0 <= (pos2 = text.indexOf(search, pos1))) { |
113 | result.append(text.substring(pos1, pos2)); |
114 | result.append(replace != null ? replace : ""); |
115 | pos1 = pos2 + len; |
116 | } |
117 | if (pos1 < text.length()) { |
118 | result.append(text.substring(pos1)); |
119 | } |
120 | text.setLength(0); |
121 | text.append(result); |
122 | } |
123 | |
124 | /** |
125 | * Return substring of text. Position might be negative if length is big enough. If the string |
126 | * limits are exceeded this method returns at least all characters within the boundaries. |
127 | * If no characters are within the given limits an empty string is returned. |
128 | * |
129 | * @param text Text to work on. Must not be <code>null</code>. |
130 | * @param position Starting position. Might be negative. |
131 | * @param length Maximum length to get. |
132 | * @return Substring of maximum length <code>length</code> and starting with position. |
133 | * @throws NullPointerException <code>text</code> is <code>null</code>. |
134 | */ |
135 | public static String substring(final String text, final int position, final int length) { |
136 | final int start = Math.max(0, position); |
137 | int l = position + length - start; |
138 | if (l <= 0) { |
139 | return ""; |
140 | } |
141 | int end = start + l; |
142 | if (end < text.length()) { |
143 | return text.substring(start, end); |
144 | } |
145 | return text.substring(start); |
146 | } |
147 | |
148 | /** |
149 | * Returns a readable presentation of an Object array. Something like ("a", null, 13)" if we have |
150 | * the "a", null, 13. Objects of type {@link CharSequence} are quoted. |
151 | * |
152 | * @param list List of Objects. |
153 | * @return List notation. |
154 | */ |
155 | public static String toString(final Object[] list) { |
156 | final StringBuffer buffer = new StringBuffer(30); |
157 | buffer.append("("); |
158 | if (list != null) { |
159 | for (int i = 0; i < list.length; i++) { |
160 | if (i > 0) { |
161 | buffer.append(", "); |
162 | } |
163 | if (list[i] instanceof CharSequence) { |
164 | buffer.append("\""); |
165 | buffer.append(list[i].toString()); |
166 | buffer.append("\""); |
167 | } else { |
168 | buffer.append(String.valueOf(list[i])); |
169 | } |
170 | } |
171 | } |
172 | buffer.append(")"); |
173 | return buffer.toString(); |
174 | } |
175 | |
176 | /** |
177 | * Returns a readable presentation of a Set. Something like {"a", null, "13} if we have |
178 | * "a", null, 13. Objects of type {@link CharSequence} are quoted. |
179 | * |
180 | * @param set Set of objects. |
181 | * @return Set notation for toString() results. |
182 | */ |
183 | public static String toString(final Set set) { |
184 | final StringBuffer buffer = new StringBuffer(30); |
185 | buffer.append("{"); |
186 | if (set != null) { |
187 | Iterator e = set.iterator(); |
188 | boolean notFirst = false; |
189 | while (e.hasNext()) { |
190 | if (notFirst) { |
191 | buffer.append(", "); |
192 | } else { |
193 | notFirst = true; |
194 | } |
195 | final Object obj = e.next(); |
196 | if (obj instanceof CharSequence) { |
197 | buffer.append("\""); |
198 | buffer.append(String.valueOf(obj)); |
199 | buffer.append("\""); |
200 | } else { |
201 | buffer.append(String.valueOf(obj)); |
202 | } |
203 | } |
204 | } |
205 | buffer.append("}"); |
206 | return buffer.toString(); |
207 | } |
208 | |
209 | /** |
210 | * Returns a readable presentation of a Map. Something like "{a=2, b=null, c=12}" if the |
211 | * Map contains (a, 2), (b, null), (c, 12). |
212 | * |
213 | * @param map Map of objects mappings. |
214 | * @return Set notation for toString() results. |
215 | */ |
216 | public static String toString(final Map map) { |
217 | final StringBuffer buffer = new StringBuffer(30); |
218 | buffer.append("{"); |
219 | if (map != null) { |
220 | Iterator e = map.entrySet().iterator(); |
221 | boolean notFirst = false; |
222 | while (e.hasNext()) { |
223 | if (notFirst) { |
224 | buffer.append(", "); |
225 | } else { |
226 | notFirst = true; |
227 | } |
228 | final Map.Entry entry = (Map.Entry) e.next(); |
229 | buffer.append(String.valueOf(entry.getKey())); |
230 | buffer.append("="); |
231 | final Object value = entry.getValue(); |
232 | if (value instanceof CharSequence) { |
233 | buffer.append("\""); |
234 | buffer.append(String.valueOf(value)); |
235 | buffer.append("\""); |
236 | } else { |
237 | buffer.append(String.valueOf(value)); |
238 | } |
239 | } |
240 | } |
241 | buffer.append("}"); |
242 | return buffer.toString(); |
243 | } |
244 | |
245 | /** |
246 | * Evaluates toString at the elements of a Set and returns them as line separated Strings. |
247 | * After the last element no carriage return is inserted. |
248 | * |
249 | * @param set Set of objects. |
250 | * @return List of toString() results. |
251 | */ |
252 | public static String asLines(final Set set) { |
253 | final StringBuffer buffer = new StringBuffer(30); |
254 | if (set != null) { |
255 | Iterator e = set.iterator(); |
256 | boolean notFirst = false; |
257 | while (e.hasNext()) { |
258 | if (notFirst) { |
259 | buffer.append("\n"); |
260 | } else { |
261 | notFirst = true; |
262 | } |
263 | buffer.append(String.valueOf(e.next())); |
264 | } |
265 | } |
266 | return buffer.toString(); |
267 | } |
268 | |
269 | |
270 | /** |
271 | * Quotes a <code>String</code>. A a quote character " is appended at the |
272 | * beginning and the end of the <code>String</code>. If a quote character occurs |
273 | * within the string it is replaced by two quotes. |
274 | * |
275 | * @param unquoted the unquoted <code>String</code>, must not be <code>null</code> |
276 | * @return quoted <code>String</code> |
277 | * @throws NullPointerException if <code>unquoted == null</code> |
278 | */ |
279 | public static String quote(final String unquoted) { |
280 | StringBuffer result = new StringBuffer(unquoted.length() + 4); |
281 | result.append('\"'); |
282 | |
283 | for (int i = 0; i < unquoted.length(); i++) { |
284 | if (unquoted.charAt(i) == '\"') { |
285 | result.append("\"\""); |
286 | } else { |
287 | result.append(unquoted.charAt(i)); |
288 | } |
289 | } |
290 | result.append('\"'); |
291 | return result.toString(); |
292 | } |
293 | |
294 | /** |
295 | * Tests if given <code>String</code> begins with a letter and contains |
296 | * only letters and digits. |
297 | * |
298 | * @param text test this |
299 | * @return is <code>text</code> only made of letters and digits and has |
300 | * a leading letter? |
301 | * @throws NullPointerException if <code>text == null</code> |
302 | */ |
303 | public static boolean isLetterDigitString(final String text) { |
304 | if (text.length() <= 0) { |
305 | return false; |
306 | } |
307 | if (!Character.isLetter(text.charAt(0))) { |
308 | return false; |
309 | } |
310 | for (int i = 1; i < text.length(); i++) { |
311 | if (!Character.isLetterOrDigit(text.charAt(i))) { |
312 | return false; |
313 | } |
314 | } |
315 | return true; |
316 | } |
317 | |
318 | /** |
319 | * Get amount of spaces. |
320 | * |
321 | * @param length number of spaces |
322 | * @return String contains exactly <code>number</code> spaces |
323 | */ |
324 | public static StringBuffer getSpaces(final int length) { |
325 | final StringBuffer buffer = new StringBuffer(length >= 0 ? length : 0); |
326 | for (int i = 0; i < length; i++) { |
327 | buffer.append(' '); |
328 | } |
329 | return buffer; |
330 | } |
331 | |
332 | /** |
333 | * Get last dot separated string part. |
334 | * |
335 | * @param full String with dots in it. Also <code>null</code> is accepted. |
336 | * @return All after the last dot in <code>full</code>. Is never <code>null</code>. |
337 | */ |
338 | public static String getLastDotString(final String full) { |
339 | if (full == null) { |
340 | return ""; |
341 | } |
342 | final int p = full.lastIndexOf('.'); |
343 | if (p < 0) { |
344 | return full; |
345 | } |
346 | return full.substring(p + 1); |
347 | } |
348 | |
349 | /** |
350 | * Get last two dot separated string part. |
351 | * |
352 | * @param full String with dots in it. Also <code>null</code> is accepted. |
353 | * @return All after the next to last dot in <code>full</code>. Is never <code>null</code>. |
354 | */ |
355 | public static String getLastTwoDotStrings(final String full) { |
356 | if (full == null) { |
357 | return ""; |
358 | } |
359 | final int p = full.lastIndexOf('.'); |
360 | if (p < 1) { |
361 | return full; |
362 | } |
363 | final int q = full.lastIndexOf('.', p - 1); |
364 | if (q < 0) { |
365 | return full; |
366 | } |
367 | return full.substring(q + 1); |
368 | } |
369 | |
370 | /** |
371 | * Get non qualified class name. |
372 | * |
373 | * @param clazz Class. |
374 | * @return Non qualified class name. |
375 | */ |
376 | public static String getClassName(final Class clazz) { |
377 | return getLastDotString(clazz.getName()); |
378 | } |
379 | |
380 | /** |
381 | * Search for first line followed by whitespace and delete this string within the whole |
382 | * text. |
383 | * <p> |
384 | * For example the following text |
385 | *<pre> |
386 | * Do you know the muffin man, |
387 | * The muffin man, the muffin man, |
388 | * Do you know the muffin man, |
389 | * Who lives on Drury Lane? |
390 | *</pre> |
391 | * will be converted into: |
392 | *<pre> |
393 | *Do you know the muffin man, |
394 | *The muffin man, the muffin man, |
395 | *Do you know the muffin man, |
396 | *Who lives on Drury Lane? |
397 | *</pre> |
398 | * |
399 | * @param buffer Work on this text. |
400 | */ |
401 | public static void deleteLineLeadingWhitespace(final StringBuffer buffer) { |
402 | int current = 0; |
403 | int lastLf = -1; |
404 | |
405 | // detect position of last line feed before content starts (lastLf) |
406 | while (current < buffer.length()) { |
407 | if (!Character.isWhitespace(buffer.charAt(current))) { |
408 | break; |
409 | } |
410 | if ('\n' == buffer.charAt(current)) { |
411 | lastLf = current; |
412 | } |
413 | current++; |
414 | } |
415 | // string from last whitespace line feed until first non whitespace |
416 | final String empty = buffer.substring(lastLf + 1, current); |
417 | |
418 | // delete this string out of the text |
419 | if (empty.length() > 0) { |
420 | // System.out.println(string2Hex(empty)); |
421 | buffer.delete(lastLf + 1 , current); // delete first occurence |
422 | replace(buffer, "\n" + empty, "\n"); // delete same whitespace on all following lines |
423 | } |
424 | } |
425 | |
426 | /** |
427 | * Return a String like it appears in an property file. Thus certain characters are escaped. |
428 | * |
429 | * @param value Escape this value. |
430 | * @return Escaped form. |
431 | */ |
432 | public static String escapeProperty(final String value) { |
433 | Properties newprops = new Properties(); |
434 | newprops.put("key", value); |
435 | ByteArrayOutputStream out = new ByteArrayOutputStream(); |
436 | try { |
437 | newprops.store(out, null); |
438 | } catch (IOException e) { |
439 | // should never occur |
440 | throw new RuntimeException(e); |
441 | } |
442 | try { |
443 | final String file = out.toString("ISO-8859-1"); |
444 | return file.substring(file.indexOf('\n') + 1 + "key=".length()).trim(); |
445 | } catch (UnsupportedEncodingException e) { |
446 | // should never occur |
447 | throw new RuntimeException(e); |
448 | } |
449 | } |
450 | |
451 | /** |
452 | * Trim an integer with leading spaces to a given maximum length. If <code>length</code> is |
453 | * shorter than the String representation of <code>number</code> no digit is cut. So the |
454 | * resulting String might be longer than <code>length</code>. |
455 | * |
456 | * @param number Format this long. |
457 | * @param length Maximum length. Must not be bigger than 20 and less than 1. |
458 | * @return String with minimum <code>length</code>, trimmed with leading spaces. |
459 | */ |
460 | public static final String alignRight(final long number, final int length) { |
461 | return alignRight("" + number, length); |
462 | } |
463 | |
464 | /** |
465 | * Trim a String with leading spaces to a given maximum length. |
466 | * |
467 | * @param string Format this string. |
468 | * @param length Minimum length. Must not be bigger than 20 and less than 1. |
469 | * @return String with minimum <code>length</code>, trimmed with leading spaces. |
470 | */ |
471 | public static final String alignRight(final String string, final int length) { |
472 | if (length > FORMATED_SPACES.length()) { |
473 | throw new IllegalArgumentException("maximum length " + FORMATED_SPACES + " exceeded: " |
474 | + length); |
475 | } |
476 | if (length < 1) { |
477 | throw new IllegalArgumentException("length must be bigger than 0: " + length); |
478 | } |
479 | final String temp = FORMATED_SPACES + string; |
480 | return temp.substring(Math.min(temp.length() - length, FORMATED_SPACES.length())); |
481 | } |
482 | |
483 | /** |
484 | * Trim an integer with leading zeros to a given maximum length. |
485 | * |
486 | * @param number Format this long. |
487 | * @param length Maximum length. Must not be bigger than 20 and less than 1. |
488 | * @return String with minimum <code>length</code>, trimmed with leading spaces. |
489 | */ |
490 | public static final String format(final long number, final int length) { |
491 | if (length > FORMATED_ZERO.length()) { |
492 | throw new IllegalArgumentException("maximum length " + FORMATED_ZERO + " exceeded: " |
493 | + length); |
494 | } |
495 | if (length < 1) { |
496 | throw new IllegalArgumentException("length must be bigger than 0: " + length); |
497 | } |
498 | final String temp = FORMATED_ZERO + number; |
499 | return temp.substring(Math.min(temp.length() - length, FORMATED_ZERO.length())); |
500 | } |
501 | |
502 | /** |
503 | * Get a hex string representation for an byte array. |
504 | * |
505 | * @param data <code>byte</code> array to work on |
506 | * @return hex String of hex codes. |
507 | */ |
508 | public static String byte2Hex(final byte[] data) { |
509 | |
510 | StringBuffer buffer = new StringBuffer(); |
511 | for (int i = 0; i < data.length; i++) { |
512 | String b = Integer.toHexString(255 & data[i]); |
513 | if (i != 0) { |
514 | if (0 != i % 16) { |
515 | buffer.append(" "); |
516 | } else { |
517 | buffer.append("\n"); |
518 | } |
519 | } |
520 | if (b.length() < 2) { |
521 | buffer.append("0"); |
522 | } |
523 | buffer.append(b.toUpperCase(Locale.US)); |
524 | } |
525 | return buffer.toString(); |
526 | } |
527 | |
528 | /** |
529 | * Get a hex string representation for a String. Uses UTF-8 encoding. |
530 | * |
531 | * @param data String to work on |
532 | * @return hex String of hex codes. |
533 | */ |
534 | public static String string2Hex(final String data) { |
535 | try { |
536 | return byte2Hex(data.getBytes("UTF8")); |
537 | } catch (UnsupportedEncodingException e) { |
538 | // should not happen |
539 | throw new RuntimeException(e); |
540 | } |
541 | } |
542 | |
543 | /** |
544 | * Get a hex string representation for a String. |
545 | * |
546 | * @param data String to work on |
547 | * @param encoding Use this String encoding. |
548 | * @return hex String of hex codes. |
549 | * @throws UnsupportedEncodingException Encoding not supported. |
550 | */ |
551 | public static String string2Hex(final String data, final String encoding) |
552 | throws UnsupportedEncodingException { |
553 | return byte2Hex(data.getBytes(encoding)); |
554 | } |
555 | |
556 | /** |
557 | * Get a byte array of a hex string representation. |
558 | * |
559 | * @param hex Hex string representation of data. |
560 | * @return Data array. |
561 | * @throws IllegalArgumentException Padding wrong or illegal hexadecimal character. |
562 | */ |
563 | public static byte[] hex2byte(final String hex) { |
564 | |
565 | StringBuffer buffer = new StringBuffer(hex.length()); |
566 | char c; |
567 | for (int i = 0; i < hex.length(); i++) { |
568 | c = hex.charAt(i); |
569 | if (!Character.isWhitespace(c)) { |
570 | if (!Character.isLetterOrDigit(c)) { |
571 | throw new IllegalArgumentException("Illegal hex char"); |
572 | } |
573 | buffer.append(c); |
574 | } |
575 | } |
576 | if (buffer.length() % 2 != 0) { |
577 | throw new IllegalArgumentException("Bad padding"); |
578 | } |
579 | byte[] result = new byte[buffer.length() / 2]; |
580 | for (int i = 0; i < buffer.length() / 2; i++) { |
581 | try { |
582 | result[i] = (byte) Integer.parseInt(buffer.substring(2 * i, 2 * i + 2), 16); |
583 | } catch (Exception e) { |
584 | throw new IllegalArgumentException("Illegal hex char"); |
585 | } |
586 | } |
587 | return result; |
588 | } |
589 | |
590 | /** |
591 | * Get a String out of a hex string representation. Uses UTF-8 encoding. |
592 | * |
593 | * @param hex Hex string representation of data. |
594 | * @return Data as String. |
595 | * @throws IllegalArgumentException Padding wrong or illegal hexadecimal character. |
596 | */ |
597 | public static String hex2String(final String hex) { |
598 | try { |
599 | return new String(hex2byte(hex), "UTF8"); |
600 | } catch (UnsupportedEncodingException e) { |
601 | // should not happen |
602 | throw new RuntimeException(e); |
603 | } |
604 | } |
605 | |
606 | /** |
607 | * Get a String out of a hex string representation. |
608 | * |
609 | * @param hex Hex string representation of data. |
610 | * @param encoding Use this String encoding. |
611 | * @return Data as String. |
612 | * @throws UnsupportedEncodingException Encoding not supported. |
613 | * @throws IllegalArgumentException Padding wrong or illegal hexadecimal character. |
614 | */ |
615 | public static String hex2String(final String hex, final String encoding) |
616 | throws UnsupportedEncodingException { |
617 | return new String(hex2byte(hex), encoding); |
618 | } |
619 | |
620 | /** |
621 | * Get platform dependent line separator. (<code>"\n"</code> on UNIX). |
622 | * |
623 | * @return Platform dependent line separator. |
624 | */ |
625 | public static String getSystemLineSeparator() { |
626 | return (SystemUtils.LINE_SEPARATOR != null ? SystemUtils.LINE_SEPARATOR |
627 | : "\n"); |
628 | } |
629 | |
630 | /** |
631 | * Creates String with platform dependent line ends. If <code>text</code> is <code>null</code> |
632 | * or empty nothing is changed. At the end of the String the platform dependent line end is |
633 | * added whether or not the original text ends with such a sequence. |
634 | * |
635 | * @param text Text with CR or CR LF as line end markers. Might be <code>null</code>. |
636 | * @return Text with platform dependent line ends. |
637 | */ |
638 | public static String useSystemLineSeparator(final String text) { |
639 | if (text == null) { |
640 | return null; |
641 | } |
642 | final StringBuffer buffer = new StringBuffer(text.length()); |
643 | final BufferedReader reader = new BufferedReader(new StringReader(text)); |
644 | final String separator = getSystemLineSeparator(); |
645 | String line; |
646 | try { |
647 | while (null != (line = reader.readLine())) { |
648 | buffer.append(line); |
649 | buffer.append(separator); |
650 | } |
651 | } catch (IOException e) { |
652 | throw new RuntimeException(e); |
653 | } |
654 | return buffer.toString(); |
655 | } |
656 | |
657 | /** |
658 | * Split String by given delimiter. |
659 | * "a:b:c" is converted to "a", "b", "c". |
660 | * "a:b:c:" is converted to "a", "b", "c", "". |
661 | * |
662 | * @param text Text to split. |
663 | * @param delimiter Split at these points. |
664 | * @return Split text. |
665 | */ |
666 | public static String[] split(final String text, final String delimiter) { |
667 | final List list = new ArrayList(); |
668 | int start = 0; |
669 | int found = -delimiter.length(); |
670 | while (-1 < (found = text.indexOf(delimiter, start))) { |
671 | list.add(text.substring(start, found)); |
672 | start = found + delimiter.length(); |
673 | } |
674 | list.add(text.substring(start)); |
675 | return (String[]) list.toArray(ArrayUtils.EMPTY_STRING_ARRAY); |
676 | } |
677 | |
678 | /** |
679 | * <p>Escapes the characters in a <code>String</code> using XML entities.</p> |
680 | * |
681 | * <p>For example: <tt>"bread" & "butter"</tt> => |
682 | * <tt>&quot;bread&quot; &amp; &quot;butter&quot;</tt>. |
683 | * </p> |
684 | * |
685 | * <p>Supports only the five basic XML entities (gt, lt, quot, amp, apos). |
686 | * Does not support DTDs or external entities.</p> |
687 | * |
688 | * <p>Note that unicode characters greater than 0x7f are currently escaped to |
689 | * their numerical \\u equivalent. This may change in future releases. </p> |
690 | * |
691 | * @param value The <code>String</code> to escape, may be null. |
692 | * @return A new escaped <code>String</code>, <code>null</code> if null string input |
693 | * @see #unescapeXml(java.lang.String) |
694 | */ |
695 | public static String escapeXml(final String value) { |
696 | return StringEscapeUtils.escapeXml(value); |
697 | } |
698 | |
699 | /** |
700 | * <p>Unescapes a string containing XML entity escapes to a string |
701 | * containing the actual Unicode characters corresponding to the |
702 | * escapes.</p> |
703 | * |
704 | * <p>Supports only the five basic XML entities (gt, lt, quot, amp, apos). |
705 | * Does not support DTDs or external entities.</p> |
706 | * |
707 | * <p>Note that numerical \\u unicode codes are unescaped to their respective |
708 | * unicode characters. This may change in future releases. </p> |
709 | * |
710 | * @param value The <code>String</code> to unescape, may be null. |
711 | * @return A new unescaped <code>String</code>, <code>null</code> if null string input |
712 | * @see #escapeXml(String) |
713 | */ |
714 | public static String unescapeXml(final String value) { |
715 | return StringEscapeUtils.unescapeXml(value); |
716 | } |
717 | |
718 | /** |
719 | * Does a given string is not an element of a given string array? |
720 | * |
721 | * @param lookFor Look for this string. |
722 | * @param array The array we look through. |
723 | * @return Is the given string not an element of the array? |
724 | */ |
725 | public static boolean isNotIn(final String lookFor, final String[] array) { |
726 | if (lookFor == null || lookFor.length() <= 0) { |
727 | return false; |
728 | } |
729 | for (int i = 0; i < array.length; i++) { |
730 | if (lookFor.equals(array[i])) { |
731 | return false; |
732 | } |
733 | } |
734 | return true; |
735 | } |
736 | |
737 | /** |
738 | * Does a given string is an element of a given string array? |
739 | * |
740 | * @param lookFor Look for this string. |
741 | * @param array The array we look through. |
742 | * @return Is the given string an element of the array? |
743 | */ |
744 | public static boolean isIn(final String lookFor, final String[] array) { |
745 | return !isNotIn(lookFor, array); |
746 | } |
747 | |
748 | |
749 | } |