1 52 53 package freemarker.template.utility; 54 55 import java.io.UnsupportedEncodingException ; 56 import java.util.*; 57 import freemarker.template.Template; 58 import freemarker.core.ParseException; 59 import freemarker.core.Environment; 60 61 66 public class StringUtil { 67 private static final char[] ESCAPES = createEscapes(); 68 69 72 73 77 public static String HTMLEnc(String s) { 78 int ln = s.length(); 79 for (int i = 0; i < ln; i++) { 80 char c = s.charAt(i); 81 if (c == '<' || c == '>' || c == '&' || c == '"') { 82 StringBuffer b = 83 new StringBuffer (s.substring(0, i)); 84 switch (c) { 85 case '<': b.append("<"); break; 86 case '>': b.append(">"); break; 87 case '&': b.append("&"); break; 88 case '"': b.append("""); break; 89 } 90 i++; 91 int next = i; 92 while (i < ln) { 93 c = s.charAt(i); 94 if (c == '<' || c == '>' || c == '&' || c == '"') { 95 b.append(s.substring(next, i)); 96 switch (c) { 97 case '<': b.append("<"); break; 98 case '>': b.append(">"); break; 99 case '&': b.append("&"); break; 100 case '"': b.append("""); break; 101 } 102 next = i + 1; 103 } 104 i++; 105 } 106 if (next < ln) b.append(s.substring(next)); 107 s = b.toString(); 108 break; 109 } } return s; 112 } 113 114 118 public static String XMLEnc(String s) { 119 int ln = s.length(); 120 for (int i = 0; i < ln; i++) { 121 char c = s.charAt(i); 122 if (c == '<' || c == '>' || c == '&' || c == '"' || c == '\'') { 123 StringBuffer b = 124 new StringBuffer (s.substring(0, i)); 125 switch (c) { 126 case '<': b.append("<"); break; 127 case '>': b.append(">"); break; 128 case '&': b.append("&"); break; 129 case '"': b.append("""); break; 130 case '\'': b.append("'"); break; 131 } 132 i++; 133 int next = i; 134 while (i < ln) { 135 c = s.charAt(i); 136 if (c == '<' || c == '>' || c == '&' || c == '"' || c == '\'') { 137 b.append(s.substring(next, i)); 138 switch (c) { 139 case '<': b.append("<"); break; 140 case '>': b.append(">"); break; 141 case '&': b.append("&"); break; 142 case '"': b.append("""); break; 143 case '\'': b.append("'"); break; 144 } 145 next = i + 1; 146 } 147 i++; 148 } 149 if (next < ln) b.append(s.substring(next)); 150 s = b.toString(); 151 break; 152 } } return s; 155 } 156 157 161 public static String XMLEncNA(String s) { 162 int ln = s.length(); 163 for (int i = 0; i < ln; i++) { 164 char c = s.charAt(i); 165 if (c == '<' || c == '>' || c == '&' || c == '"') { 166 StringBuffer b = 167 new StringBuffer (s.substring(0, i)); 168 switch (c) { 169 case '<': b.append("<"); break; 170 case '>': b.append(">"); break; 171 case '&': b.append("&"); break; 172 case '"': b.append("""); break; 173 } 174 i++; 175 int next = i; 176 while (i < ln) { 177 c = s.charAt(i); 178 if (c == '<' || c == '>' || c == '&' || c == '"') { 179 b.append(s.substring(next, i)); 180 switch (c) { 181 case '<': b.append("<"); break; 182 case '>': b.append(">"); break; 183 case '&': b.append("&"); break; 184 case '"': b.append("""); break; 185 } 186 next = i + 1; 187 } 188 i++; 189 } 190 if (next < ln) b.append(s.substring(next)); 191 s = b.toString(); 192 break; 193 } } return s; 196 } 197 198 203 public static String XMLEncQAttr(String s) { 204 int ln = s.length(); 205 for (int i = 0; i < ln; i++) { 206 char c = s.charAt(i); 207 if (c == '<' || c == '&' || c == '"') { 208 StringBuffer b = 209 new StringBuffer (s.substring(0, i)); 210 switch (c) { 211 case '<': b.append("<"); break; 212 case '&': b.append("&"); break; 213 case '"': b.append("""); break; 214 } 215 i++; 216 int next = i; 217 while (i < ln) { 218 c = s.charAt(i); 219 if (c == '<' || c == '&' || c == '"') { 220 b.append(s.substring(next, i)); 221 switch (c) { 222 case '<': b.append("<"); break; 223 case '&': b.append("&"); break; 224 case '"': b.append("""); break; 225 } 226 next = i + 1; 227 } 228 i++; 229 } 230 if (next < ln) { 231 b.append(s.substring(next)); 232 } 233 s = b.toString(); 234 break; 235 } } return s; 238 } 239 240 244 public static String XMLEncNQG(String s) { 245 int ln = s.length(); 246 for (int i = 0; i < ln; i++) { 247 char c = s.charAt(i); 248 if (c == '<' || c == '&') { 249 StringBuffer b = 250 new StringBuffer (s.substring(0, i)); 251 switch (c) { 252 case '<': b.append("<"); break; 253 case '&': b.append("&"); break; 254 } 255 i++; 256 int next = i; 257 while (i < ln) { 258 c = s.charAt(i); 259 if (c == '<' || c == '&') { 260 b.append(s.substring(next, i)); 261 switch (c) { 262 case '<': b.append("<"); break; 263 case '&': b.append("&"); break; 264 } 265 next = i + 1; 266 } 267 i++; 268 } 269 if (next < ln) b.append(s.substring(next)); 270 s = b.toString(); 271 break; 272 } } return s; 275 } 276 277 281 public static String RTFEnc(String s) { 282 int ln = s.length(); 283 for (int i = 0; i < ln; i++) { 284 char c = s.charAt(i); 285 if (c == '\\' || c == '{' || c == '}') { 286 StringBuffer b = 287 new StringBuffer (s.substring(0, i)); 288 switch (c) { 289 case '\\': b.append("\\\\"); break; 290 case '{': b.append("\\{"); break; 291 case '}': b.append("\\}"); break; 292 } 293 i++; 294 int next = i; 295 while (i < ln) { 296 c = s.charAt(i); 297 if (c == '\\' || c == '{' || c == '}') { 298 b.append(s.substring(next, i)); 299 switch (c) { 300 case '\\': b.append("\\\\"); break; 301 case '{': b.append("\\{"); break; 302 case '}': b.append("\\}"); break; 303 } 304 next = i + 1; 305 } 306 i++; 307 } 308 if (next < ln) b.append(s.substring(next)); 309 s = b.toString(); 310 break; 311 } } return s; 314 } 315 316 319 public static String URLEnc(String s, String charset) 320 throws UnsupportedEncodingException { 321 int ln = s.length(); 322 int i; 323 for (i = 0; i < ln; i++) { 324 char c = s.charAt(i); 325 if (!(c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' 326 || c >= '0' && c <= '9' 327 || c == '_' || c == '-' || c == '.' || c == '!' || c == '~' 328 || c >= '\'' && c <= '*')) { 329 break; 330 } 331 } 332 if (i == ln) { 333 return s; 335 } 336 337 StringBuffer b = new StringBuffer (ln + ln / 3 + 2); 338 b.append(s.substring(0, i)); 339 340 int encstart = i; 341 for (i++; i < ln; i++) { 342 char c = s.charAt(i); 343 if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' 344 || c >= '0' && c <= '9' 345 || c == '_' || c == '-' || c == '.' || c == '!' || c == '~' 346 || c >= '\'' && c <= '*') { 347 if (encstart != -1) { 348 byte[] o = s.substring(encstart, i).getBytes(charset); 349 for (int j = 0; j < o.length; j++) { 350 b.append('%'); 351 byte bc = o[j]; 352 int c1 = bc & 0x0F; 353 int c2 = (bc >> 4) & 0x0F; 354 b.append((char) (c2 < 10 ? c2 + '0' : c2 - 10 + 'A')); 355 b.append((char) (c1 < 10 ? c1 + '0' : c1 - 10 + 'A')); 356 } 357 encstart = -1; 358 } 359 b.append(c); 360 } else { 361 if (encstart == -1) { 362 encstart = i; 363 } 364 } 365 } 366 if (encstart != -1) { 367 byte[] o = s.substring(encstart, i).getBytes(charset); 368 for (int j = 0; j < o.length; j++) { 369 b.append('%'); 370 byte bc = o[j]; 371 int c1 = bc & 0x0F; 372 int c2 = (bc >> 4) & 0x0F; 373 b.append((char) (c2 < 10 ? c2 + '0' : c2 - 10 + 'A')); 374 b.append((char) (c1 < 10 ? c1 + '0' : c1 - 10 + 'A')); 375 } 376 } 377 378 return b.toString(); 379 } 380 381 private static char[] createEscapes() 382 { 383 char[] escapes = new char['\\' + 1]; 384 for(int i = 0; i < 32; ++i) 385 { 386 escapes[i] = 1; 387 } 388 escapes['\\'] = '\\'; 389 escapes['\''] = '\''; 390 escapes['"'] = '"'; 391 escapes['<'] = 'l'; 392 escapes['>'] = 'g'; 393 escapes['&'] = 'a'; 394 escapes['\b'] = 'b'; 395 escapes['\t'] = 't'; 396 escapes['\n'] = 'n'; 397 escapes['\f'] = 'f'; 398 escapes['\r'] = 'r'; 399 escapes['$'] = '$'; 400 return escapes; 401 } 402 403 public static String FTLStringLiteralEnc(String s) 404 { 405 StringBuffer buf = null; 406 int l = s.length(); 407 int el = ESCAPES.length; 408 for(int i = 0; i < l; i++) 409 { 410 char c = s.charAt(i); 411 if(c < el) 412 { 413 char escape = ESCAPES[c]; 414 switch(escape) 415 { 416 case 0: 417 { 418 if (buf != null) { 419 buf.append(c); 420 } 421 break; 422 } 423 case 1: 424 { 425 if (buf == null) { 426 buf = new StringBuffer (s.length() + 3); 427 buf.append(s.substring(0, i)); 428 } 429 buf.append("\\x00"); 432 int c2 = (c >> 4) & 0x0F; 433 c = (char) (c & 0x0F); 434 buf.append((char) (c2 < 10 ? c2 + '0' : c2 - 10 + 'A')); 435 buf.append((char) (c < 10 ? c + '0' : c - 10 + 'A')); 436 break; 437 } 438 default: 439 { 440 if (buf == null) { 441 buf = new StringBuffer (s.length() + 2); 442 buf.append(s.substring(0, i)); 443 } 444 buf.append('\\'); 445 buf.append(escape); 446 } 447 } 448 } else { 449 if (buf != null) { 450 buf.append(c); 451 } 452 } 453 } 454 return buf == null ? s : buf.toString(); 455 } 456 457 475 public static String FTLStringLiteralDec(String s) throws ParseException { 476 477 int idx = s.indexOf('\\'); 478 if (idx == -1) { 479 return s; 480 } 481 482 int lidx = s.length() - 1; 483 int bidx = 0; 484 StringBuffer buf = new StringBuffer (lidx); 485 do { 486 buf.append(s.substring(bidx, idx)); 487 if (idx >= lidx) { 488 throw new ParseException("The last character of string literal is backslash", 0,0); 489 } 490 char c = s.charAt(idx + 1); 491 switch (c) { 492 case '"': 493 buf.append('"'); 494 bidx = idx + 2; 495 break; 496 case '\'': 497 buf.append('\''); 498 bidx = idx + 2; 499 break; 500 case '\\': 501 buf.append('\\'); 502 bidx = idx + 2; 503 break; 504 case 'n': 505 buf.append('\n'); 506 bidx = idx + 2; 507 break; 508 case 'r': 509 buf.append('\r'); 510 bidx = idx + 2; 511 break; 512 case 't': 513 buf.append('\t'); 514 bidx = idx + 2; 515 break; 516 case 'f': 517 buf.append('\f'); 518 bidx = idx + 2; 519 break; 520 case 'b': 521 buf.append('\b'); 522 bidx = idx + 2; 523 break; 524 case 'g': 525 buf.append('>'); 526 bidx = idx + 2; 527 break; 528 case 'l': 529 buf.append('<'); 530 bidx = idx + 2; 531 break; 532 case 'a': 533 buf.append('&'); 534 bidx = idx + 2; 535 break; 536 case '{': 537 buf.append('{'); 538 bidx = idx + 2; 539 break; 540 case 'x': { 541 idx += 2; 542 int x = idx; 543 int y = 0; 544 int z = lidx > idx + 3 ? idx + 3 : lidx; 545 while (idx <= z) { 546 char b = s.charAt(idx); 547 if (b >= '0' && b <= '9') { 548 y <<= 4; 549 y += b - '0'; 550 } else if (b >= 'a' && b <= 'f') { 551 y <<= 4; 552 y += b - 'a' + 10; 553 } else if (b >= 'A' && b <= 'F') { 554 y <<= 4; 555 y += b - 'A' + 10; 556 } else { 557 break; 558 } 559 idx++; 560 } 561 if (x < idx) { 562 buf.append((char) y); 563 } else { 564 throw new ParseException("Invalid \\x escape in a string literal",0,0); 565 } 566 bidx = idx; 567 break; 568 } 569 default: 570 throw new ParseException("Invalid escape sequence (\\" + c + ") in a string literal",0,0); 571 } 572 idx = s.indexOf('\\', bidx); 573 } while (idx != -1); 574 buf.append(s.substring(bidx)); 575 576 return buf.toString(); 577 } 578 579 public static Locale deduceLocale(String input) { 580 Locale locale = Locale.getDefault(); 581 if (input.charAt(0) == '"') input = input.substring(1, input.length() -1); 582 StringTokenizer st = new StringTokenizer(input, ",_ "); 583 String lang = "", country = ""; 584 if (st.hasMoreTokens()) { 585 lang = st.nextToken(); 586 } 587 if (st.hasMoreTokens()) { 588 country = st.nextToken(); 589 } 590 if (!st.hasMoreTokens()) { 591 locale = new Locale(lang, country); 592 } 593 else { 594 locale = new Locale(lang, country, st.nextToken()); 595 } 596 return locale; 597 } 598 599 public static String capitalize(String s) { 600 StringTokenizer st = new StringTokenizer(s, " \t\r\n", true); 601 StringBuffer buf = new StringBuffer (s.length()); 602 while (st.hasMoreTokens()) { 603 String tok = st.nextToken(); 604 buf.append(tok.substring(0, 1).toUpperCase()); 605 buf.append(tok.substring(1).toLowerCase()); 606 } 607 return buf.toString(); 608 } 609 610 public static boolean getYesNo(String s) { 611 if (s.startsWith("\"")) { 612 s = s.substring(1, s.length() -1); 613 614 } 615 if (s.equalsIgnoreCase("n") 616 || s.equalsIgnoreCase("no") 617 || s.equalsIgnoreCase("f") 618 || s.equalsIgnoreCase("false")) { 619 return false; 620 } 621 else if (s.equalsIgnoreCase("y") 622 || s.equalsIgnoreCase("yes") 623 || s.equalsIgnoreCase("t") 624 || s.equalsIgnoreCase("true")) { 625 return true; 626 } 627 throw new IllegalArgumentException ("Illegal boolean value: " + s); 628 } 629 630 633 public static String [] split(String s, char c) { 634 int i, b, e; 635 int cnt; 636 String res[]; 637 int ln = s.length(); 638 639 i = 0; 640 cnt = 1; 641 while ((i = s.indexOf(c, i)) != -1) { 642 cnt++; 643 i++; 644 } 645 res = new String [cnt]; 646 647 i = 0; 648 b = 0; 649 while (b <= ln) { 650 e = s.indexOf(c, b); 651 if (e == -1) e = ln; 652 res[i++] = s.substring(b, e); 653 b = e + 1; 654 } 655 return res; 656 } 657 658 661 public static String [] split(String s, String sep, boolean caseInsensitive) { 662 String splitString = caseInsensitive ? sep.toLowerCase() : sep; 663 String input = caseInsensitive ? s.toLowerCase() : s; 664 int i, b, e; 665 int cnt; 666 String res[]; 667 int ln = s.length(); 668 int sln = sep.length(); 669 670 if (sln == 0) throw new IllegalArgumentException ( 671 "The separator string has 0 length"); 672 673 i = 0; 674 cnt = 1; 675 while ((i = input.indexOf(splitString, i)) != -1) { 676 cnt++; 677 i += sln; 678 } 679 res = new String [cnt]; 680 681 i = 0; 682 b = 0; 683 while (b <= ln) { 684 e = input.indexOf(splitString, b); 685 if (e == -1) e = ln; 686 res[i++] = s.substring(b, e); 687 b = e + sln; 688 } 689 return res; 690 } 691 692 698 public static String replace(String text, 699 String oldsub, 700 String newsub, 701 boolean caseInsensitive, 702 boolean firstOnly) 703 { 704 StringBuffer buf; 705 int tln; 706 int oln = oldsub.length(); 707 708 if (oln == 0) { 709 int nln = newsub.length(); 710 if (nln == 0) { 711 return text; 712 } else { 713 if (firstOnly) { 714 return newsub + text; 715 } else { 716 tln = text.length(); 717 buf = new StringBuffer (tln + (tln + 1) * nln); 718 buf.append(newsub); 719 for (int i = 0; i < tln; i++) { 720 buf.append(text.charAt(i)); 721 buf.append(newsub); 722 } 723 return buf.toString(); 724 } 725 } 726 } else { 727 oldsub = caseInsensitive ? oldsub.toLowerCase() : oldsub; 728 String input = caseInsensitive ? text.toLowerCase() : text; 729 int e = input.indexOf(oldsub); 730 if (e == -1) { 731 return text; 732 } 733 int b = 0; 734 tln = text.length(); 735 buf = new StringBuffer ( 736 tln + Math.max(newsub.length() - oln, 0) * 3); 737 do { 738 buf.append(text.substring(b, e)); 739 buf.append(newsub); 740 b = e + oln; 741 e = input.indexOf(oldsub, b); 742 } while (e != -1 && !firstOnly); 743 buf.append(text.substring(b)); 744 return buf.toString(); 745 } 746 } 747 748 751 public static String chomp(String s) { 752 if (s.endsWith("\r\n")) return s.substring(0, s.length() - 2); 753 if (s.endsWith("\r") || s.endsWith("\n")) 754 return s.substring(0, s.length() - 1); 755 return s; 756 } 757 758 763 public static String jQuote(String s) { 764 if (s == null) { 765 return "null"; 766 } 767 int ln = s.length(); 768 StringBuffer b = new StringBuffer (ln + 4); 769 b.append('"'); 770 for (int i = 0; i < ln; i++) { 771 char c = s.charAt(i); 772 if (c == '"') { 773 b.append("\\\""); 774 } else if (c == '\\') { 775 b.append("\\\\"); 776 } else if (c < 0x20) { 777 if (c == '\n') { 778 b.append("\\n"); 779 } else if (c == '\r') { 780 b.append("\\r"); 781 } else if (c == '\f') { 782 b.append("\\f"); 783 } else if (c == '\b') { 784 b.append("\\b"); 785 } else if (c == '\t') { 786 b.append("\\t"); 787 } else { 788 b.append("\\u00"); 789 int x = c / 0x10; 790 b.append((char) (x < 0xA ? x + '0' : x - 0xA + 'A')); 791 x = c & 0xF; 792 b.append((char) (x < 0xA ? x + '0' : x - 0xA + 'A')); 793 } 794 } else { 795 b.append(c); 796 } 797 } b.append('"'); 799 return b.toString(); 800 } 801 802 813 public static String javaStringEnc(String s) { 814 int ln = s.length(); 815 for (int i = 0; i < ln; i++) { 816 char c = s.charAt(i); 817 if (c == '"' || c == '\\' || c < 0x20) { 818 StringBuffer b = new StringBuffer (ln + 4); 819 b.append(s.substring(0, i)); 820 while (true) { 821 if (c == '"') { 822 b.append("\\\""); 823 } else if (c == '\\') { 824 b.append("\\\\"); 825 } else if (c < 0x20) { 826 if (c == '\n') { 827 b.append("\\n"); 828 } else if (c == '\r') { 829 b.append("\\r"); 830 } else if (c == '\f') { 831 b.append("\\f"); 832 } else if (c == '\b') { 833 b.append("\\b"); 834 } else if (c == '\t') { 835 b.append("\\t"); 836 } else { 837 b.append("\\u00"); 838 int x = c / 0x10; 839 b.append((char) 840 (x < 0xA ? x + '0' : x - 0xA + 'a')); 841 x = c & 0xF; 842 b.append((char) 843 (x < 0xA ? x + '0' : x - 0xA + 'a')); 844 } 845 } else { 846 b.append(c); 847 } 848 i++; 849 if (i >= ln) { 850 return b.toString(); 851 } 852 c = s.charAt(i); 853 } 854 } } return s; 857 } 858 859 869 public static String javaScriptStringEnc(String s) { 870 int ln = s.length(); 871 for (int i = 0; i < ln; i++) { 872 char c = s.charAt(i); 873 if (c == '"' || c == '\'' || c == '\\' || c == '>' || c < 0x20) { 874 StringBuffer b = new StringBuffer (ln + 4); 875 b.append(s.substring(0, i)); 876 while (true) { 877 if (c == '"') { 878 b.append("\\\""); 879 } else if (c == '\'') { 880 b.append("\\'"); 881 } else if (c == '\\') { 882 b.append("\\\\"); 883 } else if (c == '>') { 884 b.append("\\>"); 885 } else if (c < 0x20) { 886 if (c == '\n') { 887 b.append("\\n"); 888 } else if (c == '\r') { 889 b.append("\\r"); 890 } else if (c == '\f') { 891 b.append("\\f"); 892 } else if (c == '\b') { 893 b.append("\\b"); 894 } else if (c == '\t') { 895 b.append("\\t"); 896 } else { 897 b.append("\\x"); 898 int x = c / 0x10; 899 b.append((char) 900 (x < 0xA ? x + '0' : x - 0xA + 'A')); 901 x = c & 0xF; 902 b.append((char) 903 (x < 0xA ? x + '0' : x - 0xA + 'A')); 904 } 905 } else { 906 b.append(c); 907 } 908 i++; 909 if (i >= ln) { 910 return b.toString(); 911 } 912 c = s.charAt(i); 913 } 914 } } return s; 917 } 918 919 938 public static Map parseNameValuePairList(String s, String defaultValue) 939 throws java.text.ParseException { 940 Map map = new HashMap(); 941 942 char c = ' '; 943 int ln = s.length(); 944 int p = 0; 945 int keyStart; 946 int valueStart; 947 String key; 948 String value; 949 950 fetchLoop: while (true) { 951 while (p < ln) { 953 c = s.charAt(p); 954 if (!Character.isWhitespace(c)) { 955 break; 956 } 957 p++; 958 } 959 if (p == ln) { 960 break fetchLoop; 961 } 962 keyStart = p; 963 964 while (p < ln) { 966 c = s.charAt(p); 967 if (!(Character.isLetterOrDigit(c) || c == '_')) { 968 break; 969 } 970 p++; 971 } 972 if (keyStart == p) { 973 throw new java.text.ParseException ( 974 "Expecting letter, digit or \"_\" " 975 + "here, (the first character of the key) but found " 976 + jQuote(String.valueOf(c)) 977 + " at position " + p + ".", 978 p); 979 } 980 key = s.substring(keyStart, p); 981 982 while (p < ln) { 984 c = s.charAt(p); 985 if (!Character.isWhitespace(c)) { 986 break; 987 } 988 p++; 989 } 990 if (p == ln) { 991 if (defaultValue == null) { 992 throw new java.text.ParseException ( 993 "Expecting \":\", but reached " 994 + "the end of the string " 995 + " at position " + p + ".", 996 p); 997 } 998 value = defaultValue; 999 } else if (c != ':') { 1000 if (defaultValue == null || c != ',') { 1001 throw new java.text.ParseException ( 1002 "Expecting \":\" here, but found " 1003 + jQuote(String.valueOf(c)) 1004 + " at position " + p + ".", 1005 p); 1006 } 1007 1008 p++; 1010 1011 value = defaultValue; 1012 } else { 1013 p++; 1015 1016 while (p < ln) { 1018 c = s.charAt(p); 1019 if (!Character.isWhitespace(c)) { 1020 break; 1021 } 1022 p++; 1023 } 1024 if (p == ln) { 1025 throw new java.text.ParseException ( 1026 "Expecting the value of the key " 1027 + "here, but reached the end of the string " 1028 + " at position " + p + ".", 1029 p); 1030 } 1031 valueStart = p; 1032 1033 while (p < ln) { 1035 c = s.charAt(p); 1036 if (!(Character.isLetterOrDigit(c) || c == '_')) { 1037 break; 1038 } 1039 p++; 1040 } 1041 if (valueStart == p) { 1042 throw new java.text.ParseException ( 1043 "Expecting letter, digit or \"_\" " 1044 + "here, (the first character of the value) " 1045 + "but found " 1046 + jQuote(String.valueOf(c)) 1047 + " at position " + p + ".", 1048 p); 1049 } 1050 value = s.substring(valueStart, p); 1051 1052 while (p < ln) { 1054 c = s.charAt(p); 1055 if (!Character.isWhitespace(c)) { 1056 break; 1057 } 1058 p++; 1059 } 1060 1061 if (p < ln) { 1063 if (c != ',') { 1064 throw new java.text.ParseException ( 1065 "Excpecting \",\" or the end " 1066 + "of the string here, but found " 1067 + jQuote(String.valueOf(c)) 1068 + " at position " + p + ".", 1069 p); 1070 } else { 1071 p++; 1072 } 1073 } 1074 } 1075 1076 if (map.put(key, value) != null) { 1078 throw new java.text.ParseException ( 1079 "Dublicated key: " 1080 + jQuote(key), keyStart); 1081 } 1082 } 1083 1084 return map; 1085 } 1086 1087 1091 static public boolean isXMLID(String name) { 1092 for (int i=0; i<name.length(); i++) { 1093 char c = name.charAt(i); 1094 if (i==0) { 1095 if (c== '-' || c=='.' || Character.isDigit(c)) 1096 return false; 1097 } 1098 if (!Character.isLetterOrDigit(c) && c != ':' && c != '_' && c != '-' && c!='.') { 1099 return false; 1100 } 1101 } 1102 return true; 1103 } 1104 1105 1108 1109 static public boolean matchesName(String qname, String nodeName, String nsURI, Environment env) { 1110 String defaultNS = env.getDefaultNS(); 1111 if ((defaultNS != null) && defaultNS.equals(nsURI)) { 1112 return qname.equals(nodeName) 1113 || qname.equals(Template.DEFAULT_NAMESPACE_PREFIX + ":" + nodeName); 1114 } 1115 if ("".equals(nsURI)) { 1116 if (defaultNS != null) { 1117 return qname.equals(Template.NO_NS_PREFIX + ":" + nodeName); 1118 } else { 1119 return qname.equals(nodeName) || qname.equals(Template.NO_NS_PREFIX + ":" + nodeName); 1120 } 1121 } 1122 String prefix = env.getPrefixForNamespace(nsURI); 1123 if (prefix == null) { 1124 return false; } 1126 return qname.equals(prefix + ":" + nodeName); 1127 } 1128 1129 1137 public static String leftPad(String s, int minLength) { 1138 return leftPad(s, minLength, ' '); 1139 } 1140 1141 1150 public static String leftPad(String s, int minLength, char filling) { 1151 int ln = s.length(); 1152 if (minLength <= ln) { 1153 return s; 1154 } 1155 1156 StringBuffer res = new StringBuffer (minLength); 1157 1158 int dif = minLength - ln; 1159 for (int i = 0; i < dif; i++) { 1160 res.append(filling); 1161 } 1162 1163 res.append(s); 1164 1165 return res.toString(); 1166 } 1167 1168 1179 public static String leftPad(String s, int minLength, String filling) { 1180 int ln = s.length(); 1181 if (minLength <= ln) { 1182 return s; 1183 } 1184 1185 StringBuffer res = new StringBuffer (minLength); 1186 1187 int dif = minLength - ln; 1188 int fln = filling.length(); 1189 if (fln == 0) { 1190 throw new IllegalArgumentException ( 1191 "The \"filling\" argument can't be 0 length string."); 1192 } 1193 int cnt = dif / fln; 1194 for (int i = 0; i < cnt; i++) { 1195 res.append(filling); 1196 } 1197 cnt = dif % fln; 1198 for (int i = 0; i < cnt; i++) { 1199 res.append(filling.charAt(i)); 1200 } 1201 1202 res.append(s); 1203 1204 return res.toString(); 1205 } 1206 1207 1215 public static String rightPad(String s, int minLength) { 1216 return rightPad(s, minLength, ' '); 1217 } 1218 1219 1228 public static String rightPad(String s, int minLength, char filling) { 1229 int ln = s.length(); 1230 if (minLength <= ln) { 1231 return s; 1232 } 1233 1234 StringBuffer res = new StringBuffer (minLength); 1235 1236 res.append(s); 1237 1238 int dif = minLength - ln; 1239 for (int i = 0; i < dif; i++) { 1240 res.append(filling); 1241 } 1242 1243 return res.toString(); 1244 } 1245 1246 1259 public static String rightPad(String s, int minLength, String filling) { 1260 int ln = s.length(); 1261 if (minLength <= ln) { 1262 return s; 1263 } 1264 1265 StringBuffer res = new StringBuffer (minLength); 1266 1267 res.append(s); 1268 1269 int dif = minLength - ln; 1270 int fln = filling.length(); 1271 if (fln == 0) { 1272 throw new IllegalArgumentException ( 1273 "The \"filling\" argument can't be 0 length string."); 1274 } 1275 int start = ln % fln; 1276 int end = fln - start <= dif 1277 ? fln 1278 : start + dif; 1279 for (int i = start; i < end; i++) { 1280 res.append(filling.charAt(i)); 1281 } 1282 dif -= end - start; 1283 int cnt = dif / fln; 1284 for (int i = 0; i < cnt; i++) { 1285 res.append(filling); 1286 } 1287 cnt = dif % fln; 1288 for (int i = 0; i < cnt; i++) { 1289 res.append(filling.charAt(i)); 1290 } 1291 1292 return res.toString(); 1293 } 1294 1295} 1296 | Popular Tags |