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