1 package org.apache.maven.surefire.util.internal;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.UnsupportedEncodingException;
23 import java.nio.ByteBuffer;
24 import java.nio.CharBuffer;
25 import java.nio.charset.CharacterCodingException;
26 import java.nio.charset.Charset;
27 import java.util.StringTokenizer;
28
29
30
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
56
57
58 public class StringUtils
59 {
60 private static final byte[] HEX_CHARS = new byte[] {
61 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
62 'A', 'B', 'C', 'D', 'E', 'F' };
63
64 private static final Charset DEFAULT_CHARSET = Charset.defaultCharset();
65
66
67 public static final String FORK_STREAM_CHARSET_NAME = "ISO-8859-1";
68
69 public static String[] split( String text, String separator )
70 {
71 int max = -1;
72 StringTokenizer tok;
73 if ( separator == null )
74 {
75
76
77 tok = new StringTokenizer( text );
78 }
79 else
80 {
81 tok = new StringTokenizer( text, separator );
82 }
83
84 int listSize = tok.countTokens();
85 if ( max > 0 && listSize > max )
86 {
87 listSize = max;
88 }
89
90 String[] list = new String[listSize];
91 int i = 0;
92 int lastTokenBegin;
93 int lastTokenEnd = 0;
94 while ( tok.hasMoreTokens() )
95 {
96 if ( max > 0 && i == listSize - 1 )
97 {
98
99
100
101 String endToken = tok.nextToken();
102 lastTokenBegin = text.indexOf( endToken, lastTokenEnd );
103 list[i] = text.substring( lastTokenBegin );
104 break;
105 }
106 else
107 {
108 list[i] = tok.nextToken();
109 lastTokenBegin = text.indexOf( list[i], lastTokenEnd );
110 lastTokenEnd = lastTokenBegin + list[i].length();
111 }
112 i++;
113 }
114 return list;
115 }
116
117
118
119
120
121
122
123
124
125 public static boolean isBlank( String str )
126 {
127 return str == null || str.trim().length() == 0;
128 }
129
130
131
132
133
134
135
136
137
138
139 public static boolean isNotBlank( String str )
140 {
141 return !isBlank( str );
142 }
143
144
145
146
147
148
149
150
151
152
153 @SuppressWarnings( "checkstyle:magicnumber" )
154 public static void escapeToPrintable( StringBuilder target, CharSequence str )
155 {
156 if ( target == null )
157 {
158 throw new IllegalArgumentException( "The target buffer must not be null" );
159 }
160 if ( str == null )
161 {
162 return;
163 }
164
165 for ( int i = 0; i < str.length(); i++ )
166 {
167 char c = str.charAt( i );
168
169
170 if ( c < 32 || c > 126 || c == '\\' || c == ',' )
171 {
172 target.append( '\\' );
173 target.append( (char) HEX_CHARS[( 0xF000 & c ) >> 12] );
174 target.append( (char) HEX_CHARS[( 0x0F00 & c ) >> 8] );
175 target.append( (char) HEX_CHARS[( 0x00F0 & c ) >> 4] );
176 target.append( (char) HEX_CHARS[( 0x000F & c )] );
177 }
178 else
179 {
180 target.append( c );
181 }
182 }
183 }
184
185
186
187
188
189
190
191 public static void unescapeString( StringBuilder target, CharSequence str )
192 {
193 if ( target == null )
194 {
195 throw new IllegalArgumentException( "The target buffer must not be null" );
196 }
197 if ( str == null )
198 {
199 return;
200 }
201
202 for ( int i = 0; i < str.length(); i++ )
203 {
204 char ch = str.charAt( i );
205
206 if ( ch == '\\' )
207 {
208 target.append( (char) (
209 digit( str.charAt( ++i ) ) << 12
210 | digit( str.charAt( ++i ) ) << 8
211 | digit( str.charAt( ++i ) ) << 4
212 | digit( str.charAt( ++i ) )
213 ) );
214 }
215 else
216 {
217 target.append( ch );
218 }
219 }
220 }
221
222 private static int digit( char ch )
223 {
224 if ( ch >= 'a' )
225 {
226 return 10 + ch - 'a';
227 }
228 else if ( ch >= 'A' )
229 {
230 return 10 + ch - 'A';
231 }
232 else
233 {
234 return ch - '0';
235 }
236 }
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254 @SuppressWarnings( "checkstyle:magicnumber" )
255 public static int escapeBytesToPrintable( byte[] out, int outoff, byte[] input, int off, int len )
256 {
257 if ( out == null )
258 {
259 throw new IllegalArgumentException( "The output array must not be null" );
260 }
261 if ( input == null || input.length == 0 )
262 {
263 return 0;
264 }
265 int outputPos = outoff;
266 int end = off + len;
267 for ( int i = off; i < end; i++ )
268 {
269 byte b = input[i];
270
271
272 if ( b < 32 || b > 126 || b == '\\' || b == ',' )
273 {
274 int upper = ( 0xF0 & b ) >> 4;
275 int lower = ( 0x0F & b );
276 out[outputPos++] = '\\';
277 out[outputPos++] = HEX_CHARS[upper];
278 out[outputPos++] = HEX_CHARS[lower];
279 }
280 else
281 {
282 out[outputPos++] = b;
283 }
284 }
285
286 return outputPos - outoff;
287 }
288
289
290
291
292
293
294
295
296 public static ByteBuffer unescapeBytes( String str, String charsetName )
297 {
298 int outPos = 0;
299
300 if ( str == null )
301 {
302 return ByteBuffer.wrap( new byte[0] );
303 }
304
305 byte[] out = new byte[str.length()];
306 for ( int i = 0; i < str.length(); i++ )
307 {
308 char ch = str.charAt( i );
309
310 if ( ch == '\\' )
311 {
312 int upper = digit( str.charAt( ++i ) );
313 int lower = digit( str.charAt( ++i ) );
314 out[outPos++] = (byte) ( upper << 4 | lower );
315 }
316 else
317 {
318 out[outPos++] = (byte) ch;
319 }
320 }
321
322 Charset sourceCharset = Charset.forName( charsetName );
323 if ( !DEFAULT_CHARSET.equals( sourceCharset ) )
324 {
325 CharBuffer decodedFromSourceCharset;
326 try
327 {
328 decodedFromSourceCharset = sourceCharset.newDecoder().decode( ByteBuffer.wrap( out, 0, outPos ) );
329 ByteBuffer defaultEncoded = DEFAULT_CHARSET.encode( decodedFromSourceCharset );
330
331 return defaultEncoded;
332 }
333 catch ( CharacterCodingException e )
334 {
335
336 }
337 }
338
339 return ByteBuffer.wrap( out, 0, outPos );
340 }
341
342 public static String decode( byte[] toDecode, Charset charset )
343 {
344 try
345 {
346
347 return new String( toDecode, charset.name() );
348 }
349 catch ( UnsupportedEncodingException e )
350 {
351 throw new RuntimeException( "The JVM must support Charset " + charset, e );
352 }
353 }
354
355 public static byte[] encode( String toEncode, Charset charset )
356 {
357 try
358 {
359
360 return toEncode.getBytes( charset.name() );
361 }
362 catch ( UnsupportedEncodingException e )
363 {
364 throw new RuntimeException( "The JVM must support Charset " + charset, e );
365 }
366 }
367
368 public static byte[] encodeStringForForkCommunication( String string )
369 {
370 try
371 {
372 return string.getBytes( FORK_STREAM_CHARSET_NAME );
373 }
374 catch ( UnsupportedEncodingException e )
375 {
376 throw new RuntimeException( "The JVM must support Charset " + FORK_STREAM_CHARSET_NAME, e );
377 }
378 }
379
380
381
382
383 public static <T> T requireNonNull( T obj, String message )
384 {
385 if ( obj == null )
386 {
387 throw new NullPointerException( message );
388 }
389 return obj;
390 }
391
392
393
394
395 public static <T> T requireNonNull( T obj )
396 {
397 return requireNonNull( obj, null );
398 }
399 }