comparison backend/src/main/java/org/dive4elements/river/utils/StringUtil.java @ 5838:5aa05a7a34b7

Rename modules to more fitting names.
author Sascha L. Teichmann <teichmann@intevation.de>
date Thu, 25 Apr 2013 15:23:37 +0200
parents flys-backend/src/main/java/org/dive4elements/river/utils/StringUtil.java@18619c1e7c2a
children 4dd33b86dc61
comparison
equal deleted inserted replaced
5837:d9901a08d0a6 5838:5aa05a7a34b7
1 package org.dive4elements.river.utils;
2
3 /**
4 * Copyright (c) 2006 by Intevation GmbH
5 *
6 * @author Sascha L. Teichmann (teichmann@intevation.de)
7 * @author Ludwig Reiter (ludwig@intevation.de)
8 *
9 * This program is free software under the LGPL (&gt;=v2.1)
10 * Read the file LGPL coming with FLYS for details.
11 */
12 import java.util.Arrays;
13 import java.util.ArrayList;
14 import java.util.Locale;
15
16 import java.net.URLEncoder;
17 import java.net.URLDecoder;
18
19 import java.io.UnsupportedEncodingException;
20 import java.io.IOException;
21 import java.io.BufferedReader;
22 import java.io.StringReader;
23 import java.io.StringWriter;
24 import java.io.PrintWriter;
25
26
27 public final class StringUtil {
28 final static String NUMBER_SEPERATOR = ";";
29 final static String LINE_SEPERATOR = ":";
30
31 private StringUtil() {
32 }
33
34 public static final String double2DArrayToString(double[][] values) {
35
36 if (values == null) {
37 throw new IllegalArgumentException("keine double[][]-Werte");
38 }
39
40 StringBuilder strbuf = new StringBuilder();
41
42 for (int i=0; i < values.length; i++) {
43 if (i>0) {
44 strbuf.append(LINE_SEPERATOR);
45 }
46 for (int j=0; j < values[i].length; j++) {
47 if (j > 0) {
48 strbuf.append(NUMBER_SEPERATOR);
49 }
50 strbuf.append(values[i][j]);
51 }
52 }
53
54 return strbuf.toString();
55 }
56
57 public static final double[][] stringToDouble2DArray(String str) {
58 if (str == null || str.length() == 0) {
59 return null;
60 }
61
62 String[] lineSplit = str.split(LINE_SEPERATOR);
63 double[][] array2D = new double[lineSplit.length][];
64 for (int i=0; i < lineSplit.length; i++) {
65 String[] numberSplit = lineSplit[i].split(NUMBER_SEPERATOR);
66
67 double[] numbers = new double[numberSplit.length];
68 for (int j=0; j < numberSplit.length; j++) {
69 numbers[j] = Double.valueOf(numberSplit[j]).doubleValue();
70 }
71
72 array2D[i] = numbers;
73 }
74
75 return array2D;
76 }
77
78 /**
79 * Remove first occurrence of "[" and "]" (if both do occur).
80 * @param value String to be stripped of [] (might be null).
81 * @return input string but with [ and ] removed, or input string if no
82 * brackets were found.
83 */
84 public static final String unbracket(String value) {
85 // null- guard
86 if (value == null) return value;
87
88 int start = value.indexOf("[");
89 int end = value.indexOf("]");
90
91 if (start < 0 || end < 0) {
92 return value;
93 }
94
95 value = value.substring(start + 1, end);
96
97 return value;
98 }
99
100
101 /**
102 * From "Q=1" make "W(Q=1)".
103 * @return original string wraped in "W()" if it contains a "Q", original
104 * string otherwise.
105 */
106 public static String wWrap(String wOrQ) {
107 return (wOrQ != null && wOrQ.indexOf("Q") >=0)
108 ? "W(" + wOrQ + ")"
109 : wOrQ;
110 }
111
112
113 public static final String [] splitLines(String s) {
114 if (s == null) {
115 return null;
116 }
117 ArrayList<String> list = new ArrayList<String>();
118
119 BufferedReader in = null;
120
121 try {
122 in =
123 new BufferedReader(
124 new StringReader(s));
125
126 String line;
127
128 while ((line = in.readLine()) != null) {
129 list.add(line);
130 }
131 }
132 catch (IOException ioe) {
133 return null;
134 }
135 finally {
136 if (in != null)
137 try {
138 in.close();
139 }
140 catch (IOException ioe) {}
141 }
142
143 return list.toArray(new String[list.size()]);
144 }
145
146 public static final String concat(String [] s) {
147 return concat(s, null);
148 }
149
150 public static final String concat(String [] s, String glue) {
151 if (s == null) {
152 return null;
153 }
154 StringBuilder sb = new StringBuilder();
155 for (int i = 0; i < s.length; ++i) {
156 if (i > 0 && glue != null) {
157 sb.append(glue);
158 }
159 sb.append(s[i]);
160 }
161 return sb.toString();
162 }
163
164 public static final String [] splitAfter(String [] src, int N) {
165 if (src == null) {
166 return null;
167 }
168
169 ArrayList<String> list = new ArrayList<String>(src.length);
170 for (int i = 0; i < src.length; ++i) {
171 String s = src[i];
172 int R;
173 if (s == null || (R = s.length()) == 0) {
174 list.add(s);
175 }
176 else {
177 while (R > N) {
178 list.add(s.substring(0, N));
179 s = s.substring(N);
180 R = s.length();
181 }
182 list.add(s);
183 }
184 }
185 return list.toArray(new String[list.size()]);
186 }
187
188 public static final String [] splitQuoted(String s) {
189 return splitQuoted(s, '"');
190 }
191
192 public static final String[] fitArray(String [] src, String [] dst) {
193 if (src == null) {
194 return dst;
195 }
196 if (dst == null) {
197 return src;
198 }
199
200 if (src.length == dst.length) {
201 return src;
202 }
203
204 System.arraycopy(src, 0, dst, 0, Math.min(dst.length, src.length));
205
206 return dst;
207 }
208
209 public static final String [] splitQuoted(String s, char quoteChar) {
210 if (s == null) {
211 return null;
212 }
213 ArrayList<String> l = new ArrayList<String>();
214 int mode = 0, last_mode = 0;
215 StringBuilder sb = new StringBuilder();
216 for (int N = s.length(), i = 0; i < N; ++i) {
217 char c = s.charAt(i);
218 switch (mode) {
219 case 0: // unquoted mode
220 if (c == quoteChar) {
221 mode = 1; // to quoted mode
222 if (sb.length() > 0) {
223 l.add(sb.toString());
224 sb.setLength(0);
225 }
226 }
227 else if (c == '\\') {
228 last_mode = 0;
229 mode = 2; // escape mode
230 }
231 else if (!Character.isWhitespace(c)) {
232 sb.append(c);
233 }
234 else if (sb.length() > 0) {
235 l.add(sb.toString());
236 sb.setLength(0);
237 }
238 break;
239 case 1: // quote mode
240 if (c == '\\') {
241 last_mode = 1;
242 mode = 2; // escape mode
243 }
244 else if (c == quoteChar) { // leave quote mode
245 l.add(sb.toString());
246 sb.setLength(0);
247 mode = 0; // to unquoted mode
248 }
249 else {
250 sb.append(c);
251 }
252 break;
253 case 2: // escape mode
254 sb.append(c);
255 mode = last_mode;
256 break;
257 }
258 }
259 if (sb.length() > 0) {
260 l.add(sb.toString());
261 }
262 return l.toArray(new String[l.size()]);
263 }
264
265 public static final String [] splitUnique(String s) {
266 return splitUnique(s, "[\\s,]+");
267 }
268
269 public static final String [] splitUnique(String s, String sep) {
270 return s != null ? unique(s.split(sep)) : null;
271 }
272
273 public static final String [] unique(String [] str) {
274 if (str == null || str.length == 1) {
275 return str;
276 }
277
278 Arrays.sort(str);
279
280 for (int i = 1; i < str.length; ++i)
281 if (str[i].equals(str[i-1])) {
282 ArrayList<String> list = new ArrayList<String>(str.length);
283
284 for (int j = 0; j < i; ++j) {
285 list.add(str[j]);
286 }
287
288 String last = str[i];
289
290 for (++i; i < str.length; ++i)
291 if (!last.equals(str[i])) {
292 list.add(last = str[i]);
293 }
294
295 return list.toArray(new String[list.size()]);
296 }
297
298 return str;
299 }
300
301 public static final String [] ensureEmptyExistence(String [] str) {
302 if (str == null) {
303 return null;
304 }
305
306 for (int i = 0; i < str.length; ++i)
307 if (str[i].length() == 0) {
308 if (i != 0) { // copy to front
309 String t = str[0];
310 str[0] = str[i];
311 str[i] = t;
312 }
313 return str;
314 }
315
316 String [] n = new String[str.length+1];
317 n[0] = "";
318 System.arraycopy(str, 0, n, 1, str.length);
319 return n;
320 }
321
322 public static final String ensureWidthPadLeft(String s, int width, char pad) {
323 int N = s.length();
324 if (N >= width) {
325 return s;
326 }
327 StringBuilder sb = new StringBuilder(width);
328 for (; N < width; ++N) {
329 sb.append(pad);
330 }
331 sb.append(s);
332 return sb.toString();
333 }
334
335 public static final String [] splitWhiteSpaceWithNAsPad(
336 String s,
337 int N,
338 String pad
339 ) {
340 if (s == null) {
341 return null;
342 }
343
344 boolean copyChars = true;
345 int count = 0; // number of WS
346
347 int S = s.length();
348
349 ArrayList<String> parts = new ArrayList<String>();
350
351 StringBuilder part = new StringBuilder(S);
352
353 for (int i = 0; i < S; ++i) {
354 char c = s.charAt(i);
355 if (copyChars) { // char mode
356 if (Character.isWhitespace(c)) {
357 if (part.length() > 0) {
358 parts.add(part.toString());
359 part.setLength(0);
360 }
361 count = 1;
362 copyChars = false; // to WS mode
363 }
364 else {
365 part.append(c);
366 }
367 }
368 else { // counting WS
369 if (Character.isWhitespace(c)) {
370 ++count;
371 }
372 else {
373 while (count >= N) {// enough to insert pad?
374 parts.add(pad);
375 count -= N;
376 }
377 part.append(c);
378 count = 0;
379 copyChars = true; // back to char mode
380 }
381 }
382 } // for all chars
383
384 if (copyChars) {
385 if (part.length() > 0) {
386 parts.add(part.toString());
387 }
388 }
389 else {
390 while (count >= N) { // enough to insert pad?
391 parts.add(pad);
392 count -= N;
393 }
394 }
395
396 return parts.toArray(new String[parts.size()]);
397 }
398
399 public static final String encodeURL(String url) {
400 try {
401 return url != null
402 ? URLEncoder.encode(url, "UTF-8")
403 : "";
404 }
405 catch (UnsupportedEncodingException usee) {
406 throw new RuntimeException(usee.getLocalizedMessage());
407 }
408 }
409
410 public static final String decodeURL(String url) {
411 try {
412 return url != null
413 ? URLDecoder.decode(url, "UTF-8")
414 : "";
415 }
416 catch (UnsupportedEncodingException usee) {
417 throw new RuntimeException(usee.getLocalizedMessage());
418 }
419 }
420
421 public static final boolean isEmpty(String s) {
422 return s == null || s.length() == 0;
423 }
424
425 public static final String empty(String s) {
426 return s == null ? "" : s;
427 }
428
429
430 public static final String trim(String s) {
431 return s != null ? s.trim() : null;
432 }
433
434 public static final String uniqueWhitespaces(String s) {
435 if (s == null) {
436 return null;
437 }
438
439 boolean wasWS = false;
440 StringBuilder sb = new StringBuilder();
441
442 for (int N = s.length(), i = 0; i < N; ++i) {
443 char c = s.charAt(i);
444 if (Character.isWhitespace(c)) {
445 if (!wasWS) {
446 sb.append(c);
447 wasWS = true;
448 }
449 }
450 else {
451 sb.append(c);
452 wasWS = false;
453 }
454 }
455
456 return sb.toString();
457 }
458
459 public static final String replaceNewlines(String s) {
460 return s == null
461 ? null
462 : s.replace('\r', ' ').replace('\n', ' ');
463 }
464
465 /*
466 public static final String quoteReplacement(String s) {
467
468 if (s == null || (s.indexOf('\\') == -1 && s.indexOf('$') == -1))
469 return s;
470
471 StringBuilder sb = new StringBuilder();
472
473 for (int N = s.length(), i = 0; i < N; ++i) {
474 char c = s.charAt(i);
475 if (c == '\\' || c == '$') sb.append('\\');
476 sb.append(c);
477 }
478
479 return sb.toString();
480 }
481 */
482
483 public static final String quoteReplacement(String s) {
484
485 if (s == null) {
486 return null;
487 }
488
489 for (int N = s.length(), i = 0; i < N; ++i) { // plain check loop
490 char c = s.charAt(i);
491 if (c == '$' || c == '\\') { // first special -> StringBuilder
492 StringBuilder sb = new StringBuilder(s.substring(0, i))
493 .append('\\')
494 .append(c);
495 for (++i; i < N; ++i) { // build StringBuilder with rest
496 if ((c = s.charAt(i)) == '$' || c == '\\') {
497 sb.append('\\');
498 }
499 sb.append(c);
500 }
501 return sb.toString();
502 }
503 }
504
505 return s;
506 }
507
508 public static final String repeat(String what, int times) {
509 return repeat(what, times, new StringBuilder()).toString();
510 }
511
512 public static final StringBuilder repeat(String what, int times, StringBuilder sb) {
513 while (times-- > 0) {
514 sb.append(what);
515 }
516 return sb;
517 }
518
519 /**
520 * Returns the file name without extension.
521 */
522 public static final String cutExtension(String s) {
523 if (s == null) {
524 return null;
525 }
526 int dot = s.lastIndexOf('.');
527 return dot >= 0
528 ? s.substring(0, dot)
529 : s;
530 }
531
532 public static final String extension(String s) {
533 if (s == null) {
534 return null;
535 }
536 int dot = s.lastIndexOf('.');
537 return dot >= 0
538 ? s.substring(dot+1)
539 : s;
540 }
541
542 public static final String [] splitExtension(String x) {
543 if (x == null) {
544 return null;
545 }
546 int i = x.lastIndexOf('.');
547 return i < 0
548 ? new String[] { x, null }
549 : new String[] { x.substring(0, Math.max(0, i)), x.substring(i+1).toLowerCase() };
550 }
551
552 public static String entityEncode(String s) {
553 if (s == null || s.length() == 0) {
554 return s;
555 }
556
557 StringBuilder sb = new StringBuilder();
558 for (int i=0, N =s.length(); i < N; i++) {
559 char c = s.charAt(i);
560 switch (c) {
561 case '<':
562 sb.append("&lt;");
563 break;
564 case '>':
565 sb.append("&gt;");
566 break;
567 case '&':
568 sb.append("&amp;");
569 break;
570 default:
571 sb.append(c);
572 }
573 }
574 return sb.toString();
575 }
576
577 public static String entityDecode(String s) {
578 if (s == null || s.length() == 0) {
579 return s;
580 }
581
582 boolean amp = false;
583 StringBuilder sb = new StringBuilder();
584 StringBuilder ampbuf = new StringBuilder();
585 for (int i=0, N =s.length(); i < N; i++) {
586 char c = s.charAt(i);
587 if (amp) {
588 if (c == ';') {
589 amp = false;
590 String str = ampbuf.toString();
591 ampbuf.setLength(0);
592 if (str.equals("lt")) {
593 sb.append('<');
594 }
595 else if (str.equals("gt")) {
596 sb.append('>');
597 }
598 else if (str.equals("amp")) {
599 sb.append('&');
600 }
601 else {
602 sb.append('&').append(str).append(';');
603 }
604 }
605 else {
606 ampbuf.append(c);
607 }
608 }
609 else if (c=='&') {
610 amp = true;
611 }
612 else {
613 sb.append(c);
614 }
615
616 }
617 return sb.toString();
618 }
619
620 public static final String quote(String s) {
621 return quote(s, '"');
622 }
623
624 public static final String quote(String s, char quoteChar) {
625 if (s == null) {
626 return null;
627 }
628
629 int N = s.length();
630
631 if (N == 0)
632 return new StringBuilder(2)
633 .append(quoteChar)
634 .append(quoteChar)
635 .toString();
636
637 StringBuilder sb = null;
638
639 int i = 0;
640
641 for (; i < N; ++i) {
642 char c = s.charAt(i);
643
644 if (Character.isWhitespace(c)) {
645 sb = new StringBuilder()
646 .append(quoteChar)
647 .append(s.substring(0, i+1));
648 break;
649 }
650 else if (c == quoteChar) {
651 sb = new StringBuilder()
652 .append(quoteChar)
653 .append(s.substring(0, i))
654 .append('\\')
655 .append(quoteChar);
656 break;
657 }
658 }
659
660 if (sb == null) {
661 return s;
662 }
663
664 for (++i; i < N; ++i) {
665 char c = s.charAt(i);
666 if (c == quoteChar || c == '\\') {
667 sb.append('\\');
668 }
669
670 sb.append(c);
671 }
672
673 return sb.append(quoteChar).toString();
674 }
675
676 /*
677 public static String sprintf(String format, Object... args) {
678 return sprintf(null, format, args);
679 }
680 */
681
682 public static String sprintf(Locale locale, String format, Object ... args) {
683 StringWriter sw = new StringWriter();
684 PrintWriter pw = new PrintWriter(sw);
685 pw.printf(locale, format, args);
686 pw.flush();
687 return sw.toString();
688 }
689
690
691 public static void testQuote() {
692 System.err.println("testing quote:");
693
694 String cases [] = {
695 "", "''",
696 "test", "test",
697 "test test", "'test test'",
698 " test", "' test'",
699 "test ", "'test '",
700 " test ", "' test '",
701 "'test", "'\\'test'",
702 "'", "'\\''",
703 " ' ' ", "' \\' \\' '",
704 "te'st", "'te\\'st'"
705 };
706
707 int failed = 0;
708
709 for (int i = 0; i < cases.length; i += 2) {
710 String in = cases[i];
711 String out = cases[i+1];
712
713 String res = quote(in, '\'');
714 if (!res.equals(out)) {
715 ++failed;
716 System.err.println(
717 "quote failed on: >" + in +
718 "< result: >" + res +
719 "< expected: >" + out + "<");
720 }
721 }
722
723 int T = cases.length/2;
724
725 System.err.println("tests total: " + T);
726 System.err.println("tests failed: " + failed);
727 System.err.println("tests passed: " + (T - failed));
728 }
729
730 public static void testQuoteReplacement() {
731 System.err.println("testing quoteReplacement:");
732
733 String cases [] = {
734 "", "",
735 "test", "test",
736 "$", "\\$",
737 "\\", "\\\\",
738 "\\$", "\\\\\\$",
739 "test\\$", "test\\\\\\$",
740 "\\test", "\\\\test",
741 "test$", "test\\$",
742 "test$test", "test\\$test",
743 "$test$", "\\$test\\$"
744 };
745
746 int failed = 0;
747
748 for (int i = 0; i < cases.length; i += 2) {
749 String in = cases[i];
750 String out = cases[i+1];
751
752 String res = quoteReplacement(in);
753 if (!res.equals(out)) {
754 ++failed;
755 System.err.println(
756 "quoteReplacement failed on: '" + in +
757 "' result: '" + res +
758 "' expected: '" + out + "'");
759 }
760 }
761
762 int T = cases.length/2;
763
764 System.err.println("tests total: " + T);
765 System.err.println("tests failed: " + failed);
766 System.err.println("tests passed: " + (T - failed));
767 }
768
769 public static void testStringArray2D() {
770 int total = 0;
771 int fail = 0;
772 int passed = 0;
773
774 System.err.println("testing StringArray2D:");
775
776 double[][] testarray = {{1.0, 2.0, 3.0},
777 {1.1, 2.1, 3.1},
778 {100.2, 200.2}
779 };
780 String str = double2DArrayToString(testarray);
781
782 total += 1;
783 if (str.equals("1.0;2.0;3.0:1.1;2.1;3.1:100.2;200.2")) {
784 passed +=1;
785 }
786 else {
787 fail +=1;
788 System.err.println("Der Ergebnis-String ist nicht richtig:");
789 System.err.println(str);
790 }
791
792
793
794 double[][] testarray2 = stringToDouble2DArray(str);
795 boolean failed = false;
796
797 total +=1;
798 for (int i=0; i < testarray.length; i++)
799 for (int j=0; j < testarray[i].length; j++)
800 if (testarray[i][j] != testarray2[i][j]) {
801 System.err.println("Test scheitert bei i=" +i +" j=" +j);
802 System.err.println("alter Wert=" + testarray[i][j] +" neuer Wert=" +testarray2[i][j]);
803 failed = true;
804 }
805 if (failed) {
806 fail +=1;
807 }
808 else {
809 passed +=1;
810 }
811 System.err.println("tests total: "+ total);
812 System.err.println("tests failed: "+ fail);
813 System.err.println("tests passed: "+ passed);
814 }
815
816 public static void main(String [] args) {
817
818 testQuoteReplacement();
819 testQuote();
820 testStringArray2D();
821 }
822
823 /** Check for occurence of needle in hay, converting both to lowercase
824 * to be ignorant of cases. */
825 public static boolean containsIgnoreCase(String hay, String needle) {
826 return hay.toLowerCase().contains(needle.toLowerCase());
827 }
828 }
829 // end of file

http://dive4elements.wald.intevation.org