1 24 package org.riotfamily.common.util; 25 26 import java.io.IOException ; 27 import java.io.StringReader ; 28 import java.io.UnsupportedEncodingException ; 29 import java.net.URLDecoder ; 30 import java.net.URLEncoder ; 31 import java.text.DecimalFormat ; 32 import java.text.NumberFormat ; 33 import java.text.SimpleDateFormat ; 34 import java.util.Calendar ; 35 import java.util.Date ; 36 import java.util.regex.Matcher ; 37 import java.util.regex.Pattern ; 38 39 import org.apache.commons.logging.Log; 40 import org.apache.commons.logging.LogFactory; 41 import org.springframework.util.ClassUtils; 42 43 46 public final class FormatUtils { 47 48 private static final Log log = LogFactory.getLog(FormatUtils.class); 49 50 private static NumberFormat numberFormat = new DecimalFormat ("0.#"); 51 52 private static SimpleDateFormat dateFormat = new SimpleDateFormat ( 53 "yyyy-MM-dd HH:mm"); 54 55 private static final String OP_ADDITION = "+"; 56 57 private static final String OP_SUBTRACTION = "-"; 58 59 private static final String ENTITY_LT = "<"; 60 61 private static final String ENTITY_GT = ">"; 62 63 private static final String ENTITY_AMP = "&"; 64 65 private static final String ENTITY_QUOT = """; 66 67 private static final String BASE64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + 68 "abcdefghijklmnopqrstuvwxyz0123456789+/="; 69 70 private FormatUtils() { 71 } 72 73 76 public static String formatByteSize(long bytes) { 77 if (bytes < 1024) { 78 return numberFormat.format(bytes) + " Bytes"; 79 } 80 float kb = (float) bytes / 1024; 81 if (kb < 1024) { 82 return numberFormat.format(kb) + " KB"; 83 } 84 float mb = kb / 1024; 85 return numberFormat.format(mb) + " MB"; 86 } 87 88 95 public static String camelToTitleCase(String s) { 96 if (s == null) { 97 return null; 98 } 99 StringBuffer sb = new StringBuffer (); 100 char last = 0; 101 for (int i = 0; i < s.length(); i++) { 102 char c = s.charAt(i); 103 if (Character.isUpperCase(c) && last > 0 && !Character.isUpperCase(last)) { 104 sb.append(' '); 105 } 106 else if (Character.isDigit(c) && last > 0 && !Character.isDigit(last)) { 107 sb.append(' '); 108 } 109 if (i == 0) { 110 c = Character.toUpperCase(c); 111 } 112 sb.append(c); 113 last = c; 114 } 115 return sb.toString(); 116 } 117 118 124 public static String xmlToCamelCase(String s) { 125 StringBuffer sb = new StringBuffer (s); 126 int offset = 0; 127 int i; 128 while ((i = sb.indexOf("-", offset)) >= 0) { 129 sb.deleteCharAt(i); 130 sb.setCharAt(i, Character.toUpperCase(sb.charAt(i))); 131 offset = i; 132 } 133 return sb.toString(); 134 } 135 136 142 public static String xmlToTitleCase(String s) { 143 return camelToTitleCase(xmlToCamelCase(s)); 144 } 145 146 152 public static String propertyToTitleCase(String s) { 153 if (s == null) { 154 return null; 155 } 156 return xmlToTitleCase(s.replace('.', '-')); 157 } 158 159 166 public static String fileNameToTitleCase(String s) { 167 if (s == null) { 168 return null; 169 } 170 return propertyToTitleCase(s.replace('_', '-')); 171 } 172 173 179 public static String camelToXmlCase(String s) { 180 if (s == null) { 181 return null; 182 } 183 StringBuffer sb = new StringBuffer (); 184 boolean lastWasLower = false; 185 for (int i = 0; i < s.length(); i++) { 186 char c = s.charAt(i); 187 if (Character.isUpperCase(c)) { 188 if (lastWasLower) { 189 sb.append('-'); 190 } 191 c = Character.toLowerCase(c); 192 } 193 else { 194 lastWasLower = true; 195 } 196 sb.append(c); 197 } 198 return sb.toString(); 199 } 200 201 205 public static String combine(String [] s) { 206 StringBuffer sb = new StringBuffer (); 207 for (int i = 0; i < s.length; i++) { 208 if (s[i] != null) { 209 sb.append(s[i]); 210 if (i < s.length - 1 && s[i + 1] != null) { 211 sb.append(' '); 212 } 213 } 214 } 215 for (int j = 1; j < s.length; j++) { 216 if (s[j] != null) { 217 sb.append(' '); 218 for (int i = 0; i <= j; i++) { 219 sb.append(s[i]); 220 if (i < j && s[i + 1] != null) { 221 sb.append('-'); 222 } 223 } 224 } 225 } 226 return sb.toString(); 227 } 228 229 233 public static String truncate(String s, int length) { 234 if (s == null || s.length() <= length) { 235 return s; 236 } 237 return s.substring(0, length); 238 } 239 240 243 public static String toCssClass(String s) { 244 if (s == null) { 245 return null; 246 } 247 s = s.replaceAll("[.\\s/]", "-"); 248 s = s.replaceAll("[^\\w-_]", ""); 249 return s; 250 } 251 252 266 public static long parseMillis(String s) { 267 if (s == null) { 268 return 0; 269 } 270 long millis = 0; 271 int i = 0; 272 int length = s.length(); 273 while (i < length) { 274 long delta = 0; 275 char ch = 0; 276 for (; i < length; i++) { 277 ch = s.charAt(i); 278 if (!Character.isDigit(ch)) { 279 i++; 280 break; 281 } 282 delta *= 10; 283 delta += Character.getNumericValue(ch); 284 } 285 switch (ch) { 286 case 's': 287 case 'S': 288 default: 289 millis += 1000 * delta; 290 break; 291 292 case 'm': 293 millis += 60 * 1000 * delta; 294 break; 295 296 case 'h': 297 case 'H': 298 millis += 60L * 60 * 1000 * delta; 299 break; 300 301 case 'd': 302 case 'D': 303 millis += 24L * 60 * 60 * 1000 * delta; 304 break; 305 306 case 'w': 307 case 'W': 308 millis += 7L * 24 * 60 * 60 * 1000 * delta; 309 break; 310 311 case 'M': 312 millis += 30L * 24 * 60 * 60 * 1000 * delta; 313 break; 314 315 case 'y': 316 case 'Y': 317 millis += 365L * 24 * 60 * 60 * 1000 * delta; 318 break; 319 } 320 } 321 return millis; 322 } 323 324 329 public static String formatMillis(long millis) { 330 int hours = (int) (millis / (1000 * 60 * 60)); 331 int minutes = (int) (millis / (1000 * 60)) % 60; 332 int seconds = (int) (millis / 1000) % 60; 333 StringBuffer sb = new StringBuffer (); 334 if (hours > 0) { 335 sb.append(hours); 336 sb.append(':'); 337 } 338 if (minutes < 10 && hours > 0) { 339 sb.append(0); 340 } 341 sb.append(minutes); 342 sb.append(':'); 343 if (seconds < 10) { 344 sb.append(0); 345 } 346 sb.append(seconds); 347 return sb.toString(); 348 } 349 350 368 public static String getExtension(String filename) { 369 if (filename == null) { 370 return ""; 371 } 372 int i = filename.lastIndexOf('.'); 373 if (i <= 0 || i == filename.length() - 1 374 || filename.indexOf('/', i) != -1 375 || filename.indexOf('\\', i) != -1) { 376 377 return ""; 378 } 379 return filename.substring(i + 1); 380 } 381 382 385 public static String stripExtension(String filename) { 386 String extension = getExtension(filename); 387 return filename 388 .substring(0, filename.length() - extension.length() - 1); 389 } 390 391 406 public static Date parseDate(String s) { 407 if (s.startsWith("today")) { 408 String op = null; 409 int days = 0; 410 int months = 0; 411 int years = 0; 412 413 s = s.substring(5); 414 int i = 0; 415 int length = s.length(); 416 long delta = 0; 417 while (i < length) { 418 419 char ch = 0; 420 for (; i < length; i++) { 421 ch = s.charAt(i); 422 if (!Character.isDigit(ch)) { 423 i++; 424 break; 425 } 426 delta *= 10; 427 delta += Character.getNumericValue(ch); 428 } 429 switch (ch) { 430 case '+': 431 op = OP_ADDITION; 432 break; 433 case '-': 434 op = OP_SUBTRACTION; 435 break; 436 case 'd': 437 case 'D': 438 if (OP_ADDITION.equals(op)) { 439 days += delta; 440 } 441 else if (OP_SUBTRACTION.equals(op)) { 442 days -= delta; 443 } 444 op = null; 445 delta = 0; 446 break; 447 448 case 'w': 449 case 'W': 450 if (OP_ADDITION.equals(op)) { 451 days += 7 * delta; 452 } 453 else if (OP_SUBTRACTION.equals(op)) { 454 days -= 7 * delta; 455 } 456 op = null; 457 delta = 0; 458 break; 459 460 case 'M': 461 if (OP_ADDITION.equals(op)) { 462 months += delta; 463 } 464 else if (OP_SUBTRACTION.equals(op)) { 465 months -= delta; 466 } 467 op = null; 468 delta = 0; 469 break; 470 471 case 'y': 472 case 'Y': 473 if (OP_ADDITION.equals(op)) { 474 years += delta; 475 } 476 else if (OP_SUBTRACTION.equals(op)) { 477 years -= delta; 478 } 479 op = null; 480 delta = 0; 481 break; 482 } 483 if (delta > 0) { 484 if (OP_ADDITION.equals(op)) { 485 days += delta; 486 } 487 else if (OP_SUBTRACTION.equals(op)) { 488 days -= delta; 489 } 490 } 491 492 } 493 Calendar c = Calendar.getInstance(); 494 c.setTime(new Date ()); 495 c.add(Calendar.DATE, days); 496 c.add(Calendar.MONTH, months); 497 c.add(Calendar.YEAR, years); 498 return c.getTime(); 499 } 500 return null; 501 } 502 503 public static String formatIsoDate(Date date) { 504 return dateFormat.format(date); 505 } 506 507 511 public static String toFilename(String s) { 512 s = s.toLowerCase(); 513 s = s.replaceAll("\\s+", "_"); 514 s = s.replaceAll("[^a-z_0-9.-]", ""); 515 return s; 516 } 517 518 524 public static String xmlEscape(String input) { 525 if (input == null) { 526 return input; 527 } 528 StringBuffer filtered = new StringBuffer (input.length() + 42); 529 char c; 530 for (int i = 0; i < input.length(); i++) { 531 c = input.charAt(i); 532 if (c == '<') { 533 filtered.append(ENTITY_LT); 534 } 535 else if (c == '>') { 536 filtered.append(ENTITY_GT); 537 } 538 else if (c == '&') { 539 filtered.append(ENTITY_AMP); 540 } 541 else if (c == '"') { 542 filtered.append(ENTITY_QUOT); 543 } 544 else { 545 filtered.append(c); 546 } 547 } 548 return filtered.toString(); 549 } 550 551 public static String escapeChars(String s, String chars, char escape) { 552 StringBuffer sb = new StringBuffer (s); 553 for (int i = 0; i < sb.length(); i++) { 554 if (chars.indexOf(sb.charAt(i)) != -1) { 555 sb.insert(i, escape); 556 i++; 557 } 558 } 559 return sb.toString(); 560 } 561 562 public static String regexEscape(String s) { 563 return escapeChars(s, ".+*?{[^$", '\\'); 564 } 565 566 570 public static String uriEscape(String input) { 571 try { 572 return URLEncoder.encode(input, "UTF-8"); 573 } 574 catch (UnsupportedEncodingException e) { 575 throw new IllegalStateException (e); 576 } 577 } 578 579 583 public static String uriUnescape(String input) { 584 try { 585 return URLDecoder.decode(input, "UTF-8"); 586 } 587 catch (UnsupportedEncodingException e) { 588 throw new IllegalStateException (e); 589 } 590 } 591 592 599 public static Object [] htmlEscapeArgs(Object [] args) { 600 Object [] escapedArgs = new Object [args.length]; 601 escapedArgs = new Object [args.length]; 602 for (int i = 0; i < args.length; i++) { 603 Object arg = args[i]; 604 if (arg instanceof String ) { 605 escapedArgs[i] = xmlEscape((String ) arg); 606 } 607 else if (ClassUtils.isPrimitiveWrapper(arg.getClass()) 608 || arg instanceof Date ) { 609 610 escapedArgs[i] = arg; 611 } 612 else { 613 escapedArgs[i] = xmlEscape(arg.toString()); 614 } 615 } 616 return escapedArgs; 617 } 618 619 624 public static int extractInt(String s, String regex) { 625 Pattern pattern = Pattern.compile(regex); 626 Matcher matcher = pattern.matcher(s); 627 if (matcher.find()) { 628 String group = matcher.group(1); 629 try { 630 return Integer.parseInt(group); 631 } 632 catch (NumberFormatException e) { 633 log.error("Not a valid number: " + group); 634 } 635 } 636 return -1; 637 } 638 639 public static String stripWhitespaces(String s) { 640 return stripWhitespaces(s, false); 641 } 642 643 public static String stripWhitespaces(String s, boolean preserveBreaks) { 644 StringReader in = new StringReader (s); 645 StringBuffer sb = new StringBuffer (); 646 try { 647 boolean lineBreak = false; 648 boolean charsWritten = false; 649 int count = 0; 650 int i; 651 while ((i = in.read()) != -1) { 652 char c = (char) i; 653 if (Character.isWhitespace(c)) { 654 if (charsWritten) { 655 count++; 656 if (preserveBreaks && c == '\n') { 657 lineBreak = true; 658 } 659 } 660 } 661 else { 662 if (count > 0) { 663 sb.append(lineBreak ? '\n' : ' '); 664 count = 0; 665 lineBreak = false; 666 } 667 sb.append(c); 668 charsWritten = true; 669 } 670 } 671 } 672 catch (IOException e) { 673 } 675 finally { 676 in.close(); 677 } 678 return sb.toString(); 679 } 680 681 685 public static String decodeBase64(String s) { 686 if (s == null) { 687 return null; 688 } 689 StringBuffer sb = new StringBuffer (); 690 int c1, c2, c3; 691 int e1, e2, e3, e4; 692 for (int i = 0; i < s.length();) { 693 e1 = BASE64.indexOf(s.charAt(i++)); 694 e2 = BASE64.indexOf(s.charAt(i++)); 695 e3 = BASE64.indexOf(s.charAt(i++)); 696 e4 = BASE64.indexOf(s.charAt(i++)); 697 698 c1 = (e1 << 2) | (e2 >> 4); 699 c2 = ((e2 & 15) << 4) | (e3 >> 2); 700 c3 = ((e3 & 3) << 6) | e4; 701 702 sb.append((char) c1); 703 if (e3 != 64) { 704 sb.append((char) c2); 705 } 706 if (e4 != 64) { 707 sb.append((char) c3); 708 } 709 } 710 return sb.toString(); 711 } 712 713 } 714 | Popular Tags |