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