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 }