1 package net.sf.jpkgmk.util;
2
3 import java.io.UnsupportedEncodingException;
4 import java.nio.charset.Charset;
5 import java.util.Random;
6
7 import net.sf.jpkgmk.ParseException;
8 import net.sf.jpkgmk.prototype.PrototypeParser;
9
10 import org.apache.commons.logging.Log;
11 import org.apache.commons.logging.LogFactory;
12
13
14
15
16
17
18
19 public class StringUtil
20 {
21
22
23
24 public static class TruncationMode {
25
26
27
28
29 public static final TruncationMode START = new TruncationMode();
30
31
32
33
34 public static final TruncationMode END = new TruncationMode();
35
36 private TruncationMode() {
37 }
38 };
39
40
41 public static final String UTF8_ENCODING = "UTF-8";
42
43
44 public static final String DEFAULT_SYSTEM_CHARSET = Charset.defaultCharset().name();
45
46
47
48
49 static final byte[] HEX_CHAR_TABLE = {
50 (byte) '0', (byte) '1', (byte) '2',
51 (byte) '3', (byte) '4', (byte) '5', (byte) '6', (byte) '7',
52 (byte) '8', (byte) '9', (byte) 'a', (byte) 'b', (byte) 'c',
53 (byte) 'd', (byte) 'e', (byte) 'f' };
54
55 private static Log log = LogFactory.getLog(StringUtil.class);
56
57
58
59 private StringUtil() {
60
61 }
62
63
64
65 public static String getHexString(byte[] raw) throws UnsupportedEncodingException
66 {
67 byte[] hex = new byte[2 * raw.length];
68 int index = 0;
69
70 for (int i=0; i<raw.length; i++) {
71 byte b = raw[i];
72 int v = b & 0xFF;
73 hex[index++] = HEX_CHAR_TABLE[v >>> 4];
74 hex[index++] = HEX_CHAR_TABLE[v & 0xF];
75 }
76 return new String(hex, "ASCII");
77 }
78
79
80
81
82
83
84 public static final boolean isNullOrEmpty(String string) {
85 return (string==null || string.trim().equals(""));
86 }
87
88
89
90
91
92
93
94
95
96 public static final String replace(String path, String search, String replacement)
97 {
98 int index = path.indexOf(search);
99 if(index >= 0) {
100 String result = path.substring(0, index);
101 result += replacement;
102 result += path.substring(index + search.length());
103 return result;
104 }
105 else {
106
107 return path;
108 }
109 }
110
111
112
113
114
115
116
117 public static String createRandomStringWithBytes(int byteSize)
118 {
119 if(byteSize <= 0) {
120 throw new IllegalArgumentException("The given byteSize '" + byteSize + "' must be > 0");
121 }
122
123 StringBuffer sb = new StringBuffer();
124 Random random = new Random();
125 for (int i = 0; i < byteSize; i++) {
126
127 char oneByte = (char) (random.nextInt() % 128);
128 sb.append(oneByte);
129 }
130 return sb.toString();
131 }
132
133
134 public static boolean isInteger(String value) {
135 try {
136 Integer.parseInt(value);
137 return true;
138 }
139 catch(NumberFormatException e) {
140 return false;
141 }
142 }
143
144
145
146
147
148
149
150 public static String createString(String[] array, char delimiter) {
151 return createString(array, 0, delimiter);
152 }
153
154
155
156
157
158
159
160
161 public static String createString(String[] array, int startIndex, char delimiter) {
162 if(startIndex >= array.length) {
163 throw new ArrayIndexOutOfBoundsException("The start index '" + startIndex + "' must be smaller than array length " + array.length);
164 }
165
166 StringBuffer sb = new StringBuffer();
167 for(int i=startIndex; i<array.length; i++) {
168 sb.append(array[i]);
169
170 if(i < array.length-1) {
171 sb.append(delimiter);
172 }
173 }
174 return sb.toString();
175 }
176
177
178
179
180
181
182
183
184
185
186
187
188
189 public static String truncateToMaxLength(String inputString, int maxLength)
190 {
191 String outputString = inputString;
192
193 if((inputString != null) && (maxLength > 0) && (inputString.length() > maxLength)) {
194 outputString = inputString.substring(0, maxLength - 3) + "...";
195 }
196
197 return outputString;
198 }
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218 public static String truncateUtf8String(String text, int maxLengthInBytes, TruncationMode mode)
219 {
220 if(text == null) {
221 throw new NullPointerException("The parameter 'text' must not be null");
222 }
223
224 if(maxLengthInBytes < 3) {
225 throw new IllegalArgumentException("maxLengthInBytes < 3");
226 }
227
228 int lengthInBytes = getLengthInBytes(text, UTF8_ENCODING);
229
230
231 if(lengthInBytes <= maxLengthInBytes) {
232 return text;
233 }
234
235
236 maxLengthInBytes = maxLengthInBytes - 3;
237
238
239
240 if(lengthInBytes == text.length()) {
241 if(mode == TruncationMode.START) {
242 return "..." + text.substring(text.length() - maxLengthInBytes, text.length());
243 }
244 else {
245 return text.substring(0, maxLengthInBytes) + "...";
246 }
247 }
248
249
250 if(mode == TruncationMode.START) {
251 return truncateStart(text, maxLengthInBytes);
252 }
253 else if(mode == TruncationMode.END) {
254 return truncateEnd(text, maxLengthInBytes);
255 }
256 else {
257 throw new IllegalArgumentException("Unknown TruncationMode: " + mode);
258 }
259 }
260
261
262 private static String truncateEnd(String text, int maxLengthInBytes) {
263
264 text = text.substring(0, maxLengthInBytes);
265
266
267 int lengthInBytes = getLengthInBytes(text, UTF8_ENCODING);
268
269
270
271 if(lengthInBytes <= maxLengthInBytes) {
272 return text + "...";
273 }
274
275
276
277
278
279 for(int i = text.length() - 1; i >= 0; i--) {
280 lengthInBytes -= ((text.charAt(i) > 127) ? 2 : 1);
281
282
283
284 if(lengthInBytes <= maxLengthInBytes) {
285 return text.substring(0, i) + "...";
286 }
287 }
288
289
290 throw new IllegalStateException("Should never reach here");
291 }
292
293
294
295 private static String truncateStart(String text, int maxLengthInBytes) {
296
297 text = text.substring(text.length() - maxLengthInBytes, text.length());
298
299
300 int lengthInBytes = getLengthInBytes(text, UTF8_ENCODING);
301
302
303
304 if(lengthInBytes <= maxLengthInBytes) {
305 return "..." + text;
306 }
307
308
309
310
311
312 for(int i = 0; i < text.length(); i++) {
313 lengthInBytes -= ((text.charAt(i) > 127) ? 2 : 1);
314
315
316
317 if(lengthInBytes <= maxLengthInBytes) {
318 return "..." + text.substring(i, text.length());
319 }
320 }
321
322
323 throw new IllegalStateException("Should never reach here");
324 }
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340 public static int getLengthInBytes(String text, String charset)
341 {
342 if(text == null) {
343 throw new NullPointerException("The parameter 'text' must not be null!");
344 }
345
346 if(charset == null) {
347
348 charset = DEFAULT_SYSTEM_CHARSET;
349 }
350
351 try {
352 return text.getBytes(charset).length;
353 }
354 catch(UnsupportedEncodingException encodingException) {
355 log.warn("Unexpected encoding exception while converting string to " + charset + ": '"
356 + encodingException.getMessage().trim() + "'.");
357 return 0;
358 }
359 }
360
361
362
363
364
365
366
367
368
369 public static KeyValuePair resolveKeyValue(String someString)
370 {
371 if (someString == null) {
372 throw new NullPointerException("The parameter 'someString' must not be null");
373 }
374
375 String key = null;
376 String value = null;
377
378 int idxEqualSymbol = someString.indexOf(KeyValuePair.ASSIGNMENT_CHAR);
379 if(idxEqualSymbol != -1) {
380 key = someString.substring(0, idxEqualSymbol);
381 value = someString.substring(idxEqualSymbol+1);
382 }
383 else {
384 key = someString;
385 }
386
387 KeyValuePair result = new KeyValuePair(key, value);
388 return result;
389 }
390
391
392
393
394
395
396 public static class KeyValuePair
397 {
398
399
400
401 public static final String ASSIGNMENT_CHAR = "=";
402
403 private String key;
404 private String value;
405
406
407
408
409
410 public KeyValuePair(String key, String value) {
411 super();
412 if (key == null) {
413 throw new NullPointerException("The parameter 'key' must not be null");
414 }
415 if(key.trim().length()<=0) {
416 throw new IllegalArgumentException("The parameter 'key' must not be an empty string.");
417 }
418 this.key = key;
419 this.value = value;
420 }
421
422 public String getKey() {
423 return key;
424 }
425 public void setKey(String key) {
426 this.key = key;
427 }
428 public String getValue() {
429 return value;
430 }
431 public void setValue(String value) {
432 this.value = value;
433 }
434
435
436 }
437
438
439
440
441
442
443
444
445 public static boolean isAlphaNumeric(String stringToCheck) {
446 if (stringToCheck == null) {
447 throw new NullPointerException(
448 "The parameter 'stringToCheck' must not be null");
449 }
450
451 char[] chr = stringToCheck.toCharArray();
452 for (int i = 0; i < chr.length; i++) {
453 if(!Character.isLetterOrDigit(chr[i])) {
454 return false;
455 }
456 }
457 return true;
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479 }
480
481 public static int compare(String first, String second) {
482 if(first == null && second == null) {
483 return 0;
484 }
485 else if(first==null) {
486 return -1;
487 }
488 else {
489 return first.compareTo(second);
490 }
491 }
492
493
494 public static void validateMode(String mode) {
495 if (mode == null) {
496 throw new NullPointerException(
497 "The parameter 'mode' must not be null");
498 }
499
500 if(mode.equals("?")) {
501 return;
502 }
503 else {
504 String regexOctal = "[0-7]{3,4}";
505
506 if(!mode.matches(regexOctal)) {
507 throw new ParseException("The given mode '" + mode + "' must consist of 4 valid octal numbers.");
508 }
509 }
510 }
511
512
513
514 public static RemoveResult removePrefix(String string, String prefix) {
515
516 int indexOfKey = string.indexOf(prefix);
517 boolean hasWhitespaceSeparator = false;
518 if(string.length() > indexOfKey) {
519 char nextChar = string.charAt(indexOfKey+1);
520 if(nextChar == PrototypeParser.DEFAULT_LINE_DELIMITER) {
521 hasWhitespaceSeparator = true;
522 indexOfKey++;
523 }
524 }
525
526 String resultString = null;
527 if(string.length() > indexOfKey) {
528 resultString = string.substring(indexOfKey+1);
529 }
530
531 return new RemoveResult(resultString, hasWhitespaceSeparator);
532 }
533
534
535 public static final class RemoveResult {
536 private boolean hasWhitespaceSeparator;
537 private String cleanedString;
538
539 public RemoveResult(String cleanedString, boolean hasWhitespaceSeparator)
540 {
541 this.cleanedString = cleanedString;
542 this.hasWhitespaceSeparator = hasWhitespaceSeparator;
543 }
544
545 public boolean isHasWhitespaceSeparator() {
546 return hasWhitespaceSeparator;
547 }
548 public void setHasWhitespaceSeparator(boolean hasWhitespaceSeparator) {
549 this.hasWhitespaceSeparator = hasWhitespaceSeparator;
550 }
551 public String getCleanedString() {
552 return cleanedString;
553 }
554 public void setCleanedString(String cleanedString) {
555 this.cleanedString = cleanedString;
556 }
557
558 }
559
560
561 }