1 package org.apache.maven.shared.utils;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 import java.util.Arrays;
24 import java.util.Iterator;
25 import java.util.Locale;
26 import java.util.Map;
27 import java.util.StringTokenizer;
28
29 import javax.annotation.Nonnull;
30 import javax.annotation.Nullable;
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55 @SuppressWarnings( "JavaDoc" )
56 public class StringUtils
57 {
58
59
60
61
62
63
64
65
66 public StringUtils()
67 {
68 }
69
70
71
72
73
74
75
76
77
78
79
80
81
82 public @Nonnull static String clean( String str )
83 {
84 return ( str == null ? "" : str.trim() );
85 }
86
87
88
89
90
91
92
93
94
95
96 public static String trim( String str )
97 {
98 return ( str == null ? null : str.trim() );
99 }
100
101
102
103
104
105
106
107
108
109
110
111 public @Nonnull static String deleteWhitespace( @Nonnull String str )
112 {
113 StringBuilder buffer = new StringBuilder();
114 int sz = str.length();
115 for ( int i = 0; i < sz; i++ )
116 {
117 if ( !Character.isWhitespace( str.charAt( i ) ) )
118 {
119 buffer.append( str.charAt( i ) );
120 }
121 }
122 return buffer.toString();
123 }
124
125
126
127
128
129
130
131
132 public static boolean isNotEmpty( String str )
133 {
134 return ( ( str != null ) && ( str.length() > 0 ) );
135 }
136
137
138
139
140
141
142
143
144
145
146
147
148 public static boolean isEmpty( @Nullable String str )
149 {
150 return ( ( str == null ) || ( str.trim().length() == 0 ) );
151 }
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170 public static boolean isBlank( @Nullable String str )
171 {
172 int strLen;
173 if ( str == null || ( strLen = str.length() ) == 0 )
174 {
175 return true;
176 }
177 for ( int i = 0; i < strLen; i++ )
178 {
179 if ( !Character.isWhitespace( str.charAt( i ) ) )
180 {
181 return false;
182 }
183 }
184 return true;
185 }
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204 public static boolean isNotBlank( @Nullable String str )
205 {
206 return !isBlank( str );
207 }
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224 public static boolean equals( @Nullable String str1, @Nullable String str2 )
225 {
226 return ( str1 == null ? str2 == null : str1.equals( str2 ) );
227 }
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242 public static boolean equalsIgnoreCase( String str1, String str2 )
243 {
244 return ( str1 == null ? str2 == null : str1.equalsIgnoreCase( str2 ) );
245 }
246
247
248
249
250
251
252
253
254
255
256
257 public static int indexOfAny( String str, String... searchStrs )
258 {
259 if ( ( str == null ) || ( searchStrs == null ) )
260 {
261 return -1;
262 }
263
264 int ret = Integer.MAX_VALUE;
265
266 int tmp;
267 for ( String searchStr : searchStrs )
268 {
269 tmp = str.indexOf( searchStr );
270 if ( tmp == -1 )
271 {
272 continue;
273 }
274
275 if ( tmp < ret )
276 {
277 ret = tmp;
278 }
279 }
280
281 return ( ret == Integer.MAX_VALUE ) ? -1 : ret;
282 }
283
284
285
286
287
288
289
290
291
292
293
294 public static int lastIndexOfAny( String str, String... searchStrs )
295 {
296 if ( ( str == null ) || ( searchStrs == null ) )
297 {
298 return -1;
299 }
300 int ret = -1;
301 int tmp;
302 for ( String searchStr : searchStrs )
303 {
304 tmp = str.lastIndexOf( searchStr );
305 if ( tmp > ret )
306 {
307 ret = tmp;
308 }
309 }
310 return ret;
311 }
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327 public static String substring( String str, int start )
328 {
329 if ( str == null )
330 {
331 return null;
332 }
333
334
335 if ( start < 0 )
336 {
337 start = str.length() + start;
338 }
339
340 if ( start < 0 )
341 {
342 start = 0;
343 }
344 if ( start > str.length() )
345 {
346 return "";
347 }
348
349 return str.substring( start );
350 }
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365 public static String substring( String str, int start, int end )
366 {
367 if ( str == null )
368 {
369 return null;
370 }
371
372
373 if ( end < 0 )
374 {
375 end = str.length() + end;
376 }
377 if ( start < 0 )
378 {
379 start = str.length() + start;
380 }
381
382
383 if ( end > str.length() )
384 {
385
386 end = str.length();
387 }
388
389
390 if ( start > end )
391 {
392 return "";
393 }
394
395 if ( start < 0 )
396 {
397 start = 0;
398 }
399 if ( end < 0 )
400 {
401 end = 0;
402 }
403
404 return str.substring( start, end );
405 }
406
407
408
409
410
411
412
413
414
415
416
417
418
419 public static String left( String str, int len )
420 {
421 if ( len < 0 )
422 {
423 throw new IllegalArgumentException( "Requested String length " + len + " is less than zero" );
424 }
425 if ( ( str == null ) || ( str.length() <= len ) )
426 {
427 return str;
428 }
429 else
430 {
431 return str.substring( 0, len );
432 }
433 }
434
435
436
437
438
439
440
441
442
443
444
445
446
447 public static String right( String str, int len )
448 {
449 if ( len < 0 )
450 {
451 throw new IllegalArgumentException( "Requested String length " + len + " is less than zero" );
452 }
453 if ( ( str == null ) || ( str.length() <= len ) )
454 {
455 return str;
456 }
457 else
458 {
459 return str.substring( str.length() - len );
460 }
461 }
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477 public static String mid( String str, int pos, int len )
478 {
479 if ( ( pos < 0 ) || ( ( str != null ) && ( pos > str.length() ) ) )
480 {
481 throw new StringIndexOutOfBoundsException( "String index " + pos + " is out of bounds" );
482 }
483 if ( len < 0 )
484 {
485 throw new IllegalArgumentException( "Requested String length " + len + " is less than zero" );
486 }
487 if ( str == null )
488 {
489 return null;
490 }
491 if ( str.length() <= ( pos + len ) )
492 {
493 return str.substring( pos );
494 }
495 else
496 {
497 return str.substring( pos, pos + len );
498 }
499 }
500
501
502
503
504
505
506
507
508
509
510
511
512
513 public @Nonnull static String[] split( @Nonnull String str )
514 {
515 return split( str, null, -1 );
516 }
517
518
519
520
521 public @Nonnull static String[] split( @Nonnull String text, String separator )
522 {
523 return split( text, separator, -1 );
524 }
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544 public @Nonnull static String[] split( @Nonnull String str, String separator, int max )
545 {
546 StringTokenizer tok;
547 if ( separator == null )
548 {
549
550
551 tok = new StringTokenizer( str );
552 }
553 else
554 {
555 tok = new StringTokenizer( str, separator );
556 }
557
558 int listSize = tok.countTokens();
559 if ( ( max > 0 ) && ( listSize > max ) )
560 {
561 listSize = max;
562 }
563
564 String[] list = new String[listSize];
565 int i = 0;
566 int lastTokenBegin;
567 int lastTokenEnd = 0;
568 while ( tok.hasMoreTokens() )
569 {
570 if ( ( max > 0 ) && ( i == listSize - 1 ) )
571 {
572
573
574
575 String endToken = tok.nextToken();
576 lastTokenBegin = str.indexOf( endToken, lastTokenEnd );
577 list[i] = str.substring( lastTokenBegin );
578 break;
579 }
580 else
581 {
582 list[i] = tok.nextToken();
583 lastTokenBegin = str.indexOf( list[i], lastTokenEnd );
584 lastTokenEnd = lastTokenBegin + list[i].length();
585 }
586 i++;
587 }
588 return list;
589 }
590
591
592
593
594
595
596
597
598
599
600
601
602 public @Nonnull static String concatenate( @Nonnull Object... array )
603 {
604 return join( array, "" );
605 }
606
607
608
609
610
611
612
613
614
615
616
617
618 public @Nonnull static String join( @Nonnull Object[] array, String separator )
619 {
620 if ( separator == null )
621 {
622 separator = "";
623 }
624 int arraySize = array.length;
625 int bufSize = ( arraySize == 0 ? 0 : ( array[0].toString().length() + separator.length() ) * arraySize );
626 StringBuilder buf = new StringBuilder( bufSize );
627
628 for ( int i = 0; i < arraySize; i++ )
629 {
630 if ( i > 0 )
631 {
632 buf.append( separator );
633 }
634 buf.append( array[i] );
635 }
636 return buf.toString();
637 }
638
639
640
641
642
643
644
645
646
647
648
649
650 public @Nonnull static String join( @Nonnull Iterator<?> iterator, String separator )
651 {
652 if ( separator == null )
653 {
654 separator = "";
655 }
656 StringBuilder buf = new StringBuilder( 256 );
657 while ( iterator.hasNext() )
658 {
659 buf.append( iterator.next() );
660 if ( iterator.hasNext() )
661 {
662 buf.append( separator );
663 }
664 }
665 return buf.toString();
666 }
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682 public static String replaceOnce( @Nullable String text, char repl, char with )
683 {
684 return replace( text, repl, with, 1 );
685 }
686
687
688
689
690
691
692
693
694
695
696
697
698 public static String replace( @Nullable String text, char repl, char with )
699 {
700 return replace( text, repl, with, -1 );
701 }
702
703
704
705
706
707
708
709
710
711
712
713
714
715 public static String replace( @Nullable String text, char repl, char with, int max )
716 {
717 return replace( text, String.valueOf( repl ), String.valueOf( with ), max );
718 }
719
720
721
722
723
724
725
726
727
728
729
730
731 public static String replaceOnce( @Nullable String text, @Nullable String repl, @Nullable String with )
732 {
733 return replace( text, repl, with, 1 );
734 }
735
736
737
738
739
740
741
742
743
744
745
746
747 public static String replace( @Nullable String text, @Nullable String repl, @Nullable String with )
748 {
749 return replace( text, repl, with, -1 );
750 }
751
752
753
754
755
756
757
758
759
760
761
762
763
764 public static String replace( @Nullable String text, @Nullable String repl, @Nullable String with, int max )
765 {
766 if ( ( text == null ) || ( repl == null ) || ( with == null ) || ( repl.length() == 0 ) )
767 {
768 return text;
769 }
770
771 StringBuilder buf = new StringBuilder( text.length() );
772 int start = 0, end;
773 while ( ( end = text.indexOf( repl, start ) ) != -1 )
774 {
775 buf.append( text.substring( start, end ) ).append( with );
776 start = end + repl.length();
777
778 if ( --max == 0 )
779 {
780 break;
781 }
782 }
783 buf.append( text.substring( start ) );
784 return buf.toString();
785 }
786
787
788
789
790
791
792
793
794
795
796
797 @SuppressWarnings( "ConstantConditions" )
798 public @Nonnull static String overlayString( @Nonnull String text, @Nonnull String overlay, int start, int end )
799 {
800 if ( overlay == null )
801 {
802 throw new NullPointerException( "overlay is null" );
803 }
804 return text.substring( 0, start ) + overlay + text.substring( end );
805 }
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821 public @Nonnull static String center( @Nonnull String str, int size )
822 {
823 return center( str, size, " " );
824 }
825
826
827
828
829
830
831
832
833
834
835
836
837
838 public @Nonnull static String center( @Nonnull String str, int size, @Nonnull String delim )
839 {
840 int sz = str.length();
841 int p = size - sz;
842 if ( p < 1 )
843 {
844 return str;
845 }
846 str = leftPad( str, sz + p / 2, delim );
847 str = rightPad( str, size, delim );
848 return str;
849 }
850
851
852
853
854
855
856
857
858
859
860
861 public @Nonnull static String chomp( @Nonnull String str )
862 {
863 return chomp( str, "\n" );
864 }
865
866
867
868
869
870
871
872
873
874
875 public @Nonnull static String chomp( @Nonnull String str, @Nonnull String sep )
876 {
877 int idx = str.lastIndexOf( sep );
878 if ( idx != -1 )
879 {
880 return str.substring( 0, idx );
881 }
882 else
883 {
884 return str;
885 }
886 }
887
888
889
890
891
892
893
894
895
896 public @Nonnull static String chompLast( @Nonnull String str )
897 {
898 return chompLast( str, "\n" );
899 }
900
901
902
903
904
905
906
907
908
909 public @Nonnull static String chompLast( @Nonnull String str, @Nonnull String sep )
910 {
911 if ( str.length() == 0 )
912 {
913 return str;
914 }
915 String sub = str.substring( str.length() - sep.length() );
916 if ( sep.equals( sub ) )
917 {
918 return str.substring( 0, str.length() - sep.length() );
919 }
920 else
921 {
922 return str;
923 }
924 }
925
926
927
928
929
930
931
932
933
934
935 public @Nonnull static String getChomp( @Nonnull String str, @Nonnull String sep )
936 {
937 int idx = str.lastIndexOf( sep );
938 if ( idx == str.length() - sep.length() )
939 {
940 return sep;
941 }
942 else if ( idx != -1 )
943 {
944 return str.substring( idx );
945 }
946 else
947 {
948 return "";
949 }
950 }
951
952
953
954
955
956
957
958
959
960
961 public @Nonnull static String prechomp( @Nonnull String str, @Nonnull String sep )
962 {
963 int idx = str.indexOf( sep );
964 if ( idx != -1 )
965 {
966 return str.substring( idx + sep.length() );
967 }
968 else
969 {
970 return str;
971 }
972 }
973
974
975
976
977
978
979
980
981
982
983 public @Nonnull static String getPrechomp( @Nonnull String str, String sep )
984 {
985 int idx = str.indexOf( sep );
986 if ( idx != -1 )
987 {
988 return str.substring( 0, idx + sep.length() );
989 }
990 else
991 {
992 return "";
993 }
994 }
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009 public @Nonnull static String chop( @Nonnull String str )
1010 {
1011 if ( "".equals( str ) )
1012 {
1013 return "";
1014 }
1015 if ( str.length() == 1 )
1016 {
1017 return "";
1018 }
1019 int lastIdx = str.length() - 1;
1020 String ret = str.substring( 0, lastIdx );
1021 char last = str.charAt( lastIdx );
1022 if ( last == '\n' )
1023 {
1024 if ( ret.charAt( lastIdx - 1 ) == '\r' )
1025 {
1026 return ret.substring( 0, lastIdx - 1 );
1027 }
1028 }
1029 return ret;
1030 }
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040 public @Nonnull static String chopNewline( @Nonnull String str )
1041 {
1042 int lastIdx = str.length() - 1;
1043 char last = str.charAt( lastIdx );
1044 if ( last == '\n' )
1045 {
1046 if ( str.charAt( lastIdx - 1 ) == '\r' )
1047 {
1048 lastIdx--;
1049 }
1050 }
1051 else
1052 {
1053 lastIdx++;
1054 }
1055 return str.substring( 0, lastIdx );
1056 }
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073 public @Nonnull static String escape( @Nonnull String str )
1074 {
1075
1076
1077 int sz = str.length();
1078 StringBuilder buffer = new StringBuilder( 2 * sz );
1079 for ( int i = 0; i < sz; i++ )
1080 {
1081 char ch = str.charAt( i );
1082
1083
1084 if ( ch > 0xfff )
1085 {
1086 buffer.append( "\\u" ).append( Integer.toHexString( ch ) );
1087 }
1088 else if ( ch > 0xff )
1089 {
1090 buffer.append( "\\u0" ).append( Integer.toHexString( ch ) );
1091 }
1092 else if ( ch > 0x7f )
1093 {
1094 buffer.append( "\\u00" ).append( Integer.toHexString( ch ) );
1095 }
1096 else if ( ch < 32 )
1097 {
1098 switch ( ch )
1099 {
1100 case '\b':
1101 buffer.append( '\\' );
1102 buffer.append( 'b' );
1103 break;
1104 case '\n':
1105 buffer.append( '\\' );
1106 buffer.append( 'n' );
1107 break;
1108 case '\t':
1109 buffer.append( '\\' );
1110 buffer.append( 't' );
1111 break;
1112 case '\f':
1113 buffer.append( '\\' );
1114 buffer.append( 'f' );
1115 break;
1116 case '\r':
1117 buffer.append( '\\' );
1118 buffer.append( 'r' );
1119 break;
1120 default:
1121 if ( ch > 0xf )
1122 {
1123 buffer.append( "\\u00" ).append( Integer.toHexString( ch ) );
1124 }
1125 else
1126 {
1127 buffer.append( "\\u000" ).append( Integer.toHexString( ch ) );
1128 }
1129 break;
1130 }
1131 }
1132 else
1133 {
1134 switch ( ch )
1135 {
1136 case '\'':
1137 buffer.append( '\\' );
1138 buffer.append( '\'' );
1139 break;
1140 case '"':
1141 buffer.append( '\\' );
1142 buffer.append( '"' );
1143 break;
1144 case '\\':
1145 buffer.append( '\\' );
1146 buffer.append( '\\' );
1147 break;
1148 default:
1149 buffer.append( ch );
1150 break;
1151 }
1152 }
1153 }
1154 return buffer.toString();
1155 }
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170 public @Nonnull static String repeat( @Nonnull String str, int repeat )
1171 {
1172 StringBuilder buffer = new StringBuilder( repeat * str.length() );
1173 for ( int i = 0; i < repeat; i++ )
1174 {
1175 buffer.append( str );
1176 }
1177 return buffer.toString();
1178 }
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190 public @Nonnull static String rightPad( @Nonnull String str, int size )
1191 {
1192 return rightPad( str, size, " " );
1193 }
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207 public @Nonnull static String rightPad( @Nonnull String str, int size, @Nonnull String delim )
1208 {
1209 size = ( size - str.length() ) / delim.length();
1210 if ( size > 0 )
1211 {
1212 str += repeat( delim, size );
1213 }
1214 return str;
1215 }
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227 public @Nonnull static String leftPad( @Nonnull String str, int size )
1228 {
1229 return leftPad( str, size, " " );
1230 }
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242 public @Nonnull static String leftPad( @Nonnull String str, int size, @Nonnull String delim )
1243 {
1244 size = ( size - str.length() ) / delim.length();
1245 if ( size > 0 )
1246 {
1247 str = repeat( delim, size ) + str;
1248 }
1249 return str;
1250 }
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261 public static String strip( String str )
1262 {
1263 return strip( str, null );
1264 }
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277 public static String strip( String str, @Nullable String delim )
1278 {
1279 str = stripStart( str, delim );
1280 return stripEnd( str, delim );
1281 }
1282
1283
1284
1285
1286
1287
1288
1289
1290 public static String[] stripAll( String... strs )
1291 {
1292 return stripAll( strs, null );
1293 }
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303 public static String[] stripAll( String[] strs, @Nullable String delimiter )
1304 {
1305 if ( ( strs == null ) || ( strs.length == 0 ) )
1306 {
1307 return strs;
1308 }
1309 int sz = strs.length;
1310 String[] newArr = new String[sz];
1311 for ( int i = 0; i < sz; i++ )
1312 {
1313 newArr[i] = strip( strs[i], delimiter );
1314 }
1315 return newArr;
1316 }
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328 public static String stripEnd( String str, @Nullable String strip )
1329 {
1330 if ( str == null )
1331 {
1332 return null;
1333 }
1334 int end = str.length();
1335
1336 if ( strip == null )
1337 {
1338 while ( ( end != 0 ) && Character.isWhitespace( str.charAt( end - 1 ) ) )
1339 {
1340 end--;
1341 }
1342 }
1343 else
1344 {
1345 while ( ( end != 0 ) && ( strip.indexOf( str.charAt( end - 1 ) ) != -1 ) )
1346 {
1347 end--;
1348 }
1349 }
1350 return str.substring( 0, end );
1351 }
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363 public static String stripStart( String str, @Nullable String strip )
1364 {
1365 if ( str == null )
1366 {
1367 return null;
1368 }
1369
1370 int start = 0;
1371
1372 int sz = str.length();
1373
1374 if ( strip == null )
1375 {
1376 while ( ( start != sz ) && Character.isWhitespace( str.charAt( start ) ) )
1377 {
1378 start++;
1379 }
1380 }
1381 else
1382 {
1383 while ( ( start != sz ) && ( strip.indexOf( str.charAt( start ) ) != -1 ) )
1384 {
1385 start++;
1386 }
1387 }
1388 return str.substring( start );
1389 }
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401 public static String upperCase( String str )
1402 {
1403 if ( str == null )
1404 {
1405 return null;
1406 }
1407 return str.toUpperCase();
1408 }
1409
1410
1411
1412
1413
1414
1415
1416
1417 public static String lowerCase( String str )
1418 {
1419 if ( str == null )
1420 {
1421 return null;
1422 }
1423 return str.toLowerCase();
1424 }
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435 public static String uncapitalise( String str )
1436 {
1437 if ( str == null )
1438 {
1439 return null;
1440 }
1441 else if ( str.length() == 0 )
1442 {
1443 return "";
1444 }
1445 else
1446 {
1447 return String.valueOf( Character.toLowerCase( str.charAt( 0 ) ) ) + str.substring( 1 );
1448 }
1449 }
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460 public static String capitalise( String str )
1461 {
1462 if ( str == null )
1463 {
1464 return null;
1465 }
1466 else if ( str.length() == 0 )
1467 {
1468 return "";
1469 }
1470 else
1471 {
1472 return String.valueOf( Character.toTitleCase( str.charAt( 0 ) ) ) + str.substring( 1 );
1473 }
1474 }
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487 public static String swapCase( String str )
1488 {
1489 if ( str == null )
1490 {
1491 return null;
1492 }
1493 int sz = str.length();
1494 StringBuilder buffer = new StringBuilder( sz );
1495
1496 boolean whitespace = false;
1497 char ch;
1498 char tmp;
1499
1500 for ( int i = 0; i < sz; i++ )
1501 {
1502 ch = str.charAt( i );
1503 if ( Character.isUpperCase( ch ) )
1504 {
1505 tmp = Character.toLowerCase( ch );
1506 }
1507 else if ( Character.isTitleCase( ch ) )
1508 {
1509 tmp = Character.toLowerCase( ch );
1510 }
1511 else if ( Character.isLowerCase( ch ) )
1512 {
1513 if ( whitespace )
1514 {
1515 tmp = Character.toTitleCase( ch );
1516 }
1517 else
1518 {
1519 tmp = Character.toUpperCase( ch );
1520 }
1521 }
1522 else
1523 {
1524 tmp = ch;
1525 }
1526 buffer.append( tmp );
1527 whitespace = Character.isWhitespace( ch );
1528 }
1529 return buffer.toString();
1530 }
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544 public static String capitaliseAllWords( String str )
1545 {
1546 if ( str == null )
1547 {
1548 return null;
1549 }
1550 int sz = str.length();
1551 StringBuilder buffer = new StringBuilder( sz );
1552 boolean space = true;
1553 for ( int i = 0; i < sz; i++ )
1554 {
1555 char ch = str.charAt( i );
1556 if ( Character.isWhitespace( ch ) )
1557 {
1558 buffer.append( ch );
1559 space = true;
1560 }
1561 else if ( space )
1562 {
1563 buffer.append( Character.toTitleCase( ch ) );
1564 space = false;
1565 }
1566 else
1567 {
1568 buffer.append( ch );
1569 }
1570 }
1571 return buffer.toString();
1572 }
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585 public static String uncapitaliseAllWords( String str )
1586 {
1587 if ( str == null )
1588 {
1589 return null;
1590 }
1591 int sz = str.length();
1592 StringBuilder buffer = new StringBuilder( sz );
1593 boolean space = true;
1594 for ( int i = 0; i < sz; i++ )
1595 {
1596 char ch = str.charAt( i );
1597 if ( Character.isWhitespace( ch ) )
1598 {
1599 buffer.append( ch );
1600 space = true;
1601 }
1602 else if ( space )
1603 {
1604 buffer.append( Character.toLowerCase( ch ) );
1605 space = false;
1606 }
1607 else
1608 {
1609 buffer.append( ch );
1610 }
1611 }
1612 return buffer.toString();
1613 }
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630 public static String getNestedString( String str, @Nonnull String tag )
1631 {
1632 return getNestedString( str, tag, tag );
1633 }
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644 public static String getNestedString( String str, @Nonnull String open, @Nonnull String close )
1645 {
1646 if ( str == null )
1647 {
1648 return null;
1649 }
1650 int start = str.indexOf( open );
1651 if ( start != -1 )
1652 {
1653 int end = str.indexOf( close, start + open.length() );
1654 if ( end != -1 )
1655 {
1656 return str.substring( start + open.length(), end );
1657 }
1658 }
1659 return null;
1660 }
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672 public static int countMatches( @Nullable String str, @Nonnull String sub )
1673 {
1674 if ( sub.equals( "" ) )
1675 {
1676 return 0;
1677 }
1678 if ( str == null )
1679 {
1680 return 0;
1681 }
1682 int count = 0;
1683 int idx = 0;
1684 while ( ( idx = str.indexOf( sub, idx ) ) != -1 )
1685 {
1686 count++;
1687 idx += sub.length();
1688 }
1689 return count;
1690 }
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704 public static boolean isAlpha( String str )
1705 {
1706 if ( str == null )
1707 {
1708 return false;
1709 }
1710 int sz = str.length();
1711 for ( int i = 0; i < sz; i++ )
1712 {
1713 if ( !Character.isLetter( str.charAt( i ) ) )
1714 {
1715 return false;
1716 }
1717 }
1718 return true;
1719 }
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730 public static boolean isWhitespace( String str )
1731 {
1732 if ( str == null )
1733 {
1734 return false;
1735 }
1736 int sz = str.length();
1737 for ( int i = 0; i < sz; i++ )
1738 {
1739 if ( ( !Character.isWhitespace( str.charAt( i ) ) ) )
1740 {
1741 return false;
1742 }
1743 }
1744 return true;
1745 }
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758 public static boolean isAlphaSpace( String str )
1759 {
1760 if ( str == null )
1761 {
1762 return false;
1763 }
1764 int sz = str.length();
1765 for ( int i = 0; i < sz; i++ )
1766 {
1767 if ( ( !Character.isLetter( str.charAt( i ) ) ) && ( str.charAt( i ) != ' ' ) )
1768 {
1769 return false;
1770 }
1771 }
1772 return true;
1773 }
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785 public static boolean isAlphanumeric( String str )
1786 {
1787 if ( str == null )
1788 {
1789 return false;
1790 }
1791 int sz = str.length();
1792 for ( int i = 0; i < sz; i++ )
1793 {
1794 if ( !Character.isLetterOrDigit( str.charAt( i ) ) )
1795 {
1796 return false;
1797 }
1798 }
1799 return true;
1800 }
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813 public static boolean isAlphanumericSpace( String str )
1814 {
1815 if ( str == null )
1816 {
1817 return false;
1818 }
1819 int sz = str.length();
1820 for ( int i = 0; i < sz; i++ )
1821 {
1822 if ( ( !Character.isLetterOrDigit( str.charAt( i ) ) ) && ( str.charAt( i ) != ' ' ) )
1823 {
1824 return false;
1825 }
1826 }
1827 return true;
1828 }
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839 public static boolean isNumeric( String str )
1840 {
1841 if ( str == null )
1842 {
1843 return false;
1844 }
1845 int sz = str.length();
1846 for ( int i = 0; i < sz; i++ )
1847 {
1848 if ( !Character.isDigit( str.charAt( i ) ) )
1849 {
1850 return false;
1851 }
1852 }
1853 return true;
1854 }
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868 public @Nonnull static String defaultString( Object obj )
1869 {
1870 return defaultString( obj, "" );
1871 }
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884 public @Nonnull static String defaultString( Object obj, @Nonnull String defaultString )
1885 {
1886 return ( obj == null ) ? defaultString : obj.toString();
1887 }
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900 public static String reverse( String str )
1901 {
1902 if ( str == null )
1903 {
1904 return null;
1905 }
1906 return new StringBuffer( str ).reverse().toString();
1907 }
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920 public @Nonnull static String reverseDelimitedString( @Nonnull String str, String delimiter )
1921 {
1922
1923
1924 String[] strs = split( str, delimiter );
1925 reverseArray( strs );
1926 return join( strs, delimiter );
1927 }
1928
1929
1930
1931
1932
1933
1934
1935
1936 private static void reverseArray( @Nonnull String... array )
1937 {
1938 int i = 0;
1939 int j = array.length - 1;
1940 String tmp;
1941
1942 while ( j > i )
1943 {
1944 tmp = array[j];
1945 array[j] = array[i];
1946 array[i] = tmp;
1947 j--;
1948 i++;
1949 }
1950 }
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967 public @Nonnull static String abbreviate( @Nonnull String s, int maxWidth )
1968 {
1969 return abbreviate( s, 0, maxWidth );
1970 }
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984 public @Nonnull static String abbreviate( @Nonnull String s, int offset, int maxWidth )
1985 {
1986 if ( maxWidth < 4 )
1987 {
1988 throw new IllegalArgumentException( "Minimum abbreviation width is 4" );
1989 }
1990 if ( s.length() <= maxWidth )
1991 {
1992 return s;
1993 }
1994 if ( offset > s.length() )
1995 {
1996 offset = s.length();
1997 }
1998 if ( ( s.length() - offset ) < ( maxWidth - 3 ) )
1999 {
2000 offset = s.length() - ( maxWidth - 3 );
2001 }
2002 if ( offset <= 4 )
2003 {
2004 return s.substring( 0, maxWidth - 3 ) + "...";
2005 }
2006 if ( maxWidth < 7 )
2007 {
2008 throw new IllegalArgumentException( "Minimum abbreviation width with offset is 7" );
2009 }
2010 if ( ( offset + ( maxWidth - 3 ) ) < s.length() )
2011 {
2012 return "..." + abbreviate( s.substring( offset ), maxWidth - 3 );
2013 }
2014 return "..." + s.substring( s.length() - ( maxWidth - 3 ) );
2015 }
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029 public static String difference( @Nonnull String s1, @Nonnull String s2 )
2030 {
2031 int at = differenceAt( s1, s2 );
2032 if ( at == -1 )
2033 {
2034 return "";
2035 }
2036 return s2.substring( at );
2037 }
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047 public static int differenceAt( @Nonnull String s1, @Nonnull String s2 )
2048 {
2049 int i;
2050 for ( i = 0; ( i < s1.length() ) && ( i < s2.length() ); ++i )
2051 {
2052 if ( s1.charAt( i ) != s2.charAt( i ) )
2053 {
2054 break;
2055 }
2056 }
2057 if ( ( i < s2.length() ) || ( i < s1.length() ) )
2058 {
2059 return i;
2060 }
2061 return -1;
2062 }
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073 public static String interpolate( String text, @Nonnull Map<?, ?> namespace )
2074 {
2075 for ( Map.Entry<?, ?> entry : namespace.entrySet() )
2076 {
2077 String key = entry.getKey().toString();
2078
2079 Object obj = entry.getValue();
2080
2081 if ( obj == null )
2082 {
2083 throw new NullPointerException( "The value of the key '" + key + "' is null." );
2084 }
2085
2086 String value = obj.toString();
2087
2088 text = replace( text, "${" + key + "}", value );
2089
2090 if ( !key.contains( " " ) )
2091 {
2092 text = replace( text, "$" + key, value );
2093 }
2094 }
2095 return text;
2096 }
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111 public @Nonnull static String removeAndHump( @Nonnull String data, @Nonnull String replaceThis )
2112 {
2113 String temp;
2114
2115 StringBuilder out = new StringBuilder();
2116
2117 temp = data;
2118
2119 StringTokenizer st = new StringTokenizer( temp, replaceThis );
2120
2121 while ( st.hasMoreTokens() )
2122 {
2123 String element = st.nextToken();
2124
2125 out.append( capitalizeFirstLetter( element ) );
2126 }
2127
2128 return out.toString();
2129 }
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144 public @Nonnull static String capitalizeFirstLetter( @Nonnull String data )
2145 {
2146 char firstLetter = Character.toTitleCase( data.substring( 0, 1 ).charAt( 0 ) );
2147
2148 String restLetters = data.substring( 1 );
2149
2150 return firstLetter + restLetters;
2151 }
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166 public @Nonnull static String lowercaseFirstLetter( @Nonnull String data )
2167 {
2168 char firstLetter = Character.toLowerCase( data.substring( 0, 1 ).charAt( 0 ) );
2169
2170 String restLetters = data.substring( 1 );
2171
2172 return firstLetter + restLetters;
2173 }
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183 public @Nonnull static String addAndDeHump( @Nonnull String view )
2184 {
2185 StringBuilder sb = new StringBuilder();
2186
2187 for ( int i = 0; i < view.length(); i++ )
2188 {
2189 if ( ( i != 0 ) && Character.isUpperCase( view.charAt( i ) ) )
2190 {
2191 sb.append( '-' );
2192 }
2193
2194 sb.append( view.charAt( i ) );
2195 }
2196
2197 return sb.toString().trim().toLowerCase( Locale.ENGLISH );
2198 }
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218 public static String quoteAndEscape( @Nullable String source, char quoteChar )
2219 {
2220 return quoteAndEscape( source, quoteChar, new char[]{ quoteChar }, new char[]{ ' ' }, '\\', false );
2221 }
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233 public static String quoteAndEscape( @Nullable String source, char quoteChar, @Nonnull char[] quotingTriggers )
2234 {
2235 return quoteAndEscape( source, quoteChar, new char[]{ quoteChar }, quotingTriggers, '\\', false );
2236 }
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248 public static String quoteAndEscape( @Nullable String source, char quoteChar, @Nonnull final char[] escapedChars, char escapeChar,
2249 boolean force )
2250 {
2251 return quoteAndEscape( source, quoteChar, escapedChars, new char[]{ ' ' }, escapeChar, force );
2252 }
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264 public static String quoteAndEscape( @Nullable String source, char quoteChar, @Nonnull final char[] escapedChars,
2265 @Nonnull final char[] quotingTriggers, char escapeChar, boolean force )
2266 {
2267 if ( source == null )
2268 {
2269 return null;
2270 }
2271
2272 if ( !force && source.startsWith( Character.toString( quoteChar ) ) && source.endsWith(
2273 Character.toString( quoteChar ) ) )
2274 {
2275 return source;
2276 }
2277
2278 String escaped = escape( source, escapedChars, escapeChar );
2279
2280 boolean quote = false;
2281 if ( force )
2282 {
2283 quote = true;
2284 }
2285 else if ( !escaped.equals( source ) )
2286 {
2287 quote = true;
2288 }
2289 else
2290 {
2291 for ( char quotingTrigger : quotingTriggers )
2292 {
2293 if ( escaped.indexOf( quotingTrigger ) > -1 )
2294 {
2295 quote = true;
2296 break;
2297 }
2298 }
2299 }
2300
2301 if ( quote )
2302 {
2303 return quoteChar + escaped + quoteChar;
2304 }
2305
2306 return escaped;
2307 }
2308
2309
2310
2311
2312
2313
2314
2315
2316 public static String escape( @Nullable String source, @Nonnull final char[] escapedChars, char escapeChar )
2317 {
2318 if ( source == null )
2319 {
2320 return null;
2321 }
2322
2323 char[] eqc = new char[escapedChars.length];
2324 System.arraycopy( escapedChars, 0, eqc, 0, escapedChars.length );
2325 Arrays.sort( eqc );
2326
2327 StringBuilder buffer = new StringBuilder( source.length() );
2328
2329 for ( int i = 0; i < source.length(); i++ )
2330 {
2331 final char c = source.charAt( i );
2332 int result = Arrays.binarySearch( eqc, c );
2333
2334 if ( result > -1 )
2335 {
2336 buffer.append( escapeChar );
2337 }
2338 buffer.append( c );
2339 }
2340
2341 return buffer.toString();
2342 }
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352 public @Nonnull static String removeDuplicateWhitespace( @Nonnull String s )
2353 {
2354 StringBuilder result = new StringBuilder();
2355 int length = s.length();
2356 boolean isPreviousWhiteSpace = false;
2357 for ( int i = 0; i < length; i++ )
2358 {
2359 char c = s.charAt( i );
2360 boolean thisCharWhiteSpace = Character.isWhitespace( c );
2361 if ( !( isPreviousWhiteSpace && thisCharWhiteSpace ) )
2362 {
2363 result.append( c );
2364 }
2365 isPreviousWhiteSpace = thisCharWhiteSpace;
2366 }
2367 return result.toString();
2368 }
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379 public static String unifyLineSeparators( @Nullable String s )
2380 {
2381 return unifyLineSeparators( s, System.getProperty( "line.separator" ) );
2382 }
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394 public static String unifyLineSeparators( @Nullable String s, @Nullable String ls )
2395 {
2396 if ( s == null )
2397 {
2398 return null;
2399 }
2400
2401 if ( ls == null )
2402 {
2403 ls = System.getProperty( "line.separator" );
2404 }
2405
2406 if ( !( ls.equals( "\n" ) || ls.equals( "\r" ) || ls.equals( "\r\n" ) ) )
2407 {
2408 throw new IllegalArgumentException( "Requested line separator is invalid." );
2409 }
2410
2411 int length = s.length();
2412
2413 StringBuilder buffer = new StringBuilder( length );
2414 for ( int i = 0; i < length; i++ )
2415 {
2416 if ( s.charAt( i ) == '\r' )
2417 {
2418 if ( ( i + 1 ) < length && s.charAt( i + 1 ) == '\n' )
2419 {
2420 i++;
2421 }
2422
2423 buffer.append( ls );
2424 }
2425 else if ( s.charAt( i ) == '\n' )
2426 {
2427 buffer.append( ls );
2428 }
2429 else
2430 {
2431 buffer.append( s.charAt( i ) );
2432 }
2433 }
2434
2435 return buffer.toString();
2436 }
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457 @SuppressWarnings( "ConstantConditions" )
2458 public static boolean contains( @Nullable String str, char searchChar )
2459 {
2460 return !isEmpty( str ) && str.indexOf( searchChar ) >= 0;
2461 }
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484 public static boolean contains( @Nullable String str, @Nullable String searchStr )
2485 {
2486 return !( str == null || searchStr == null ) && str.contains( searchStr );
2487 }
2488 }