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