1 16 package org.apache.commons.lang; 17 18 import java.util.HashMap ; 19 import java.util.Map ; 20 import java.util.TreeMap ; 21 22 36 class Entities { 37 38 private static final String [][] BASIC_ARRAY = { 39 {"quot", "34"}, {"amp", "38"}, {"lt", "60"}, {"gt", "62"}, }; 44 45 private static final String [][] APOS_ARRAY = { 46 {"apos", "39"}, }; 48 49 static final String [][] ISO8859_1_ARRAY = { 51 {"nbsp", "160"}, {"iexcl", "161"}, {"cent", "162"}, {"pound", "163"}, {"curren", "164"}, {"yen", "165"}, {"brvbar", "166"}, {"sect", "167"}, {"uml", "168"}, {"copy", "169"}, {"ordf", "170"}, {"laquo", "171"}, {"not", "172"}, {"shy", "173"}, {"reg", "174"}, {"macr", "175"}, {"deg", "176"}, {"plusmn", "177"}, {"sup2", "178"}, {"sup3", "179"}, {"acute", "180"}, {"micro", "181"}, {"para", "182"}, {"middot", "183"}, {"cedil", "184"}, {"sup1", "185"}, {"ordm", "186"}, {"raquo", "187"}, {"frac14", "188"}, {"frac12", "189"}, {"frac34", "190"}, {"iquest", "191"}, {"Agrave", "192"}, {"Aacute", "193"}, {"Acirc", "194"}, {"Atilde", "195"}, {"Auml", "196"}, {"Aring", "197"}, {"AElig", "198"}, {"Ccedil", "199"}, {"Egrave", "200"}, {"Eacute", "201"}, {"Ecirc", "202"}, {"Euml", "203"}, {"Igrave", "204"}, {"Iacute", "205"}, {"Icirc", "206"}, {"Iuml", "207"}, {"ETH", "208"}, {"Ntilde", "209"}, {"Ograve", "210"}, {"Oacute", "211"}, {"Ocirc", "212"}, {"Otilde", "213"}, {"Ouml", "214"}, {"times", "215"}, {"Oslash", "216"}, {"Ugrave", "217"}, {"Uacute", "218"}, {"Ucirc", "219"}, {"Uuml", "220"}, {"Yacute", "221"}, {"THORN", "222"}, {"szlig", "223"}, {"agrave", "224"}, {"aacute", "225"}, {"acirc", "226"}, {"atilde", "227"}, {"auml", "228"}, {"aring", "229"}, {"aelig", "230"}, {"ccedil", "231"}, {"egrave", "232"}, {"eacute", "233"}, {"ecirc", "234"}, {"euml", "235"}, {"igrave", "236"}, {"iacute", "237"}, {"icirc", "238"}, {"iuml", "239"}, {"eth", "240"}, {"ntilde", "241"}, {"ograve", "242"}, {"oacute", "243"}, {"ocirc", "244"}, {"otilde", "245"}, {"ouml", "246"}, {"divide", "247"}, {"oslash", "248"}, {"ugrave", "249"}, {"uacute", "250"}, {"ucirc", "251"}, {"uuml", "252"}, {"yacute", "253"}, {"thorn", "254"}, {"yuml", "255"}, }; 148 149 static final String [][] HTML40_ARRAY = { 152 {"fnof", "402"}, {"Alpha", "913"}, {"Beta", "914"}, {"Gamma", "915"}, {"Delta", "916"}, {"Epsilon", "917"}, {"Zeta", "918"}, {"Eta", "919"}, {"Theta", "920"}, {"Iota", "921"}, {"Kappa", "922"}, {"Lambda", "923"}, {"Mu", "924"}, {"Nu", "925"}, {"Xi", "926"}, {"Omicron", "927"}, {"Pi", "928"}, {"Rho", "929"}, {"Sigma", "931"}, {"Tau", "932"}, {"Upsilon", "933"}, {"Phi", "934"}, {"Chi", "935"}, {"Psi", "936"}, {"Omega", "937"}, {"alpha", "945"}, {"beta", "946"}, {"gamma", "947"}, {"delta", "948"}, {"epsilon", "949"}, {"zeta", "950"}, {"eta", "951"}, {"theta", "952"}, {"iota", "953"}, {"kappa", "954"}, {"lambda", "955"}, {"mu", "956"}, {"nu", "957"}, {"xi", "958"}, {"omicron", "959"}, {"pi", "960"}, {"rho", "961"}, {"sigmaf", "962"}, {"sigma", "963"}, {"tau", "964"}, {"upsilon", "965"}, {"phi", "966"}, {"chi", "967"}, {"psi", "968"}, {"omega", "969"}, {"thetasym", "977"}, {"upsih", "978"}, {"piv", "982"}, {"bull", "8226"}, {"hellip", "8230"}, {"prime", "8242"}, {"Prime", "8243"}, {"oline", "8254"}, {"frasl", "8260"}, {"weierp", "8472"}, {"image", "8465"}, {"real", "8476"}, {"trade", "8482"}, {"alefsym", "8501"}, {"larr", "8592"}, {"uarr", "8593"}, {"rarr", "8594"}, {"darr", "8595"}, {"harr", "8596"}, {"crarr", "8629"}, {"lArr", "8656"}, {"uArr", "8657"}, {"rArr", "8658"}, {"dArr", "8659"}, {"hArr", "8660"}, {"forall", "8704"}, {"part", "8706"}, {"exist", "8707"}, {"empty", "8709"}, {"nabla", "8711"}, {"isin", "8712"}, {"notin", "8713"}, {"ni", "8715"}, {"prod", "8719"}, {"sum", "8721"}, {"minus", "8722"}, {"lowast", "8727"}, {"radic", "8730"}, {"prop", "8733"}, {"infin", "8734"}, {"ang", "8736"}, {"and", "8743"}, {"or", "8744"}, {"cap", "8745"}, {"cup", "8746"}, {"int", "8747"}, {"there4", "8756"}, {"sim", "8764"}, {"cong", "8773"}, {"asymp", "8776"}, {"ne", "8800"}, {"equiv", "8801"}, {"le", "8804"}, {"ge", "8805"}, {"sub", "8834"}, {"sup", "8835"}, {"sube", "8838"}, {"supe", "8839"}, {"oplus", "8853"}, {"otimes", "8855"}, {"perp", "8869"}, {"sdot", "8901"}, {"lceil", "8968"}, {"rceil", "8969"}, {"lfloor", "8970"}, {"rfloor", "8971"}, {"lang", "9001"}, {"rang", "9002"}, {"loz", "9674"}, {"spades", "9824"}, {"clubs", "9827"}, {"hearts", "9829"}, {"diams", "9830"}, 299 {"OElig", "338"}, {"oelig", "339"}, {"Scaron", "352"}, {"scaron", "353"}, {"Yuml", "376"}, {"circ", "710"}, {"tilde", "732"}, {"ensp", "8194"}, {"emsp", "8195"}, {"thinsp", "8201"}, {"zwnj", "8204"}, {"zwj", "8205"}, {"lrm", "8206"}, {"rlm", "8207"}, {"ndash", "8211"}, {"mdash", "8212"}, {"lsquo", "8216"}, {"rsquo", "8217"}, {"sbquo", "8218"}, {"ldquo", "8220"}, {"rdquo", "8221"}, {"bdquo", "8222"}, {"dagger", "8224"}, {"Dagger", "8225"}, {"permil", "8240"}, {"lsaquo", "8249"}, {"rsaquo", "8250"}, {"euro", "8364"}, }; 334 335 338 public static final Entities XML; 339 340 343 public static final Entities HTML32; 344 345 348 public static final Entities HTML40; 349 350 static { 351 XML = new Entities(); 352 XML.addEntities(BASIC_ARRAY); 353 XML.addEntities(APOS_ARRAY); 354 } 355 356 static { 357 HTML32 = new Entities(); 358 HTML32.addEntities(BASIC_ARRAY); 359 HTML32.addEntities(ISO8859_1_ARRAY); 360 } 361 362 static { 363 HTML40 = new Entities(); 364 fillWithHtml40Entities(HTML40); 365 } 366 367 static void fillWithHtml40Entities(Entities entities) { 368 entities.addEntities(BASIC_ARRAY); 369 entities.addEntities(ISO8859_1_ARRAY); 370 entities.addEntities(HTML40_ARRAY); 371 } 372 373 static interface EntityMap { 374 void add(String name, int value); 375 376 String name(int value); 377 378 int value(String name); 379 } 380 381 static class PrimitiveEntityMap implements EntityMap { 382 private Map mapNameToValue = new HashMap (); 383 private IntHashMap mapValueToName = new IntHashMap(); 384 385 public void add(String name, int value) { 386 mapNameToValue.put(name, new Integer (value)); 387 mapValueToName.put(value, name); 388 } 389 390 public String name(int value) { 391 return (String ) mapValueToName.get(value); 392 } 393 394 public int value(String name) { 395 Object value = mapNameToValue.get(name); 396 if (value == null) { 397 return -1; 398 } 399 return ((Integer ) value).intValue(); 400 } 401 } 402 403 404 static abstract class MapIntMap implements Entities.EntityMap { 405 protected Map mapNameToValue; 406 protected Map mapValueToName; 407 408 public void add(String name, int value) { 409 mapNameToValue.put(name, new Integer (value)); 410 mapValueToName.put(new Integer (value), name); 411 } 412 413 public String name(int value) { 414 return (String ) mapValueToName.get(new Integer (value)); 415 } 416 417 public int value(String name) { 418 Object value = mapNameToValue.get(name); 419 if (value == null) { 420 return -1; 421 } 422 return ((Integer ) value).intValue(); 423 } 424 } 425 426 static class HashEntityMap extends MapIntMap { 427 public HashEntityMap() { 428 mapNameToValue = new HashMap (); 429 mapValueToName = new HashMap (); 430 } 431 } 432 433 static class TreeEntityMap extends MapIntMap { 434 public TreeEntityMap() { 435 mapNameToValue = new TreeMap (); 436 mapValueToName = new TreeMap (); 437 } 438 } 439 440 static class LookupEntityMap extends PrimitiveEntityMap { 441 private String [] lookupTable; 442 private int LOOKUP_TABLE_SIZE = 256; 443 444 public String name(int value) { 445 if (value < LOOKUP_TABLE_SIZE) { 446 return lookupTable()[value]; 447 } 448 return super.name(value); 449 } 450 451 private String [] lookupTable() { 452 if (lookupTable == null) { 453 createLookupTable(); 454 } 455 return lookupTable; 456 } 457 458 private void createLookupTable() { 459 lookupTable = new String [LOOKUP_TABLE_SIZE]; 460 for (int i = 0; i < LOOKUP_TABLE_SIZE; ++i) { 461 lookupTable[i] = super.name(i); 462 } 463 } 464 } 465 466 static class ArrayEntityMap implements EntityMap { 467 protected int growBy = 100; 468 protected int size = 0; 469 protected String [] names; 470 protected int[] values; 471 472 public ArrayEntityMap() { 473 names = new String [growBy]; 474 values = new int[growBy]; 475 } 476 477 public ArrayEntityMap(int growBy) { 478 this.growBy = growBy; 479 names = new String [growBy]; 480 values = new int[growBy]; 481 } 482 483 public void add(String name, int value) { 484 ensureCapacity(size + 1); 485 names[size] = name; 486 values[size] = value; 487 size++; 488 } 489 490 protected void ensureCapacity(int capacity) { 491 if (capacity > names.length) { 492 int newSize = Math.max(capacity, size + growBy); 493 String [] newNames = new String [newSize]; 494 System.arraycopy(names, 0, newNames, 0, size); 495 names = newNames; 496 int[] newValues = new int[newSize]; 497 System.arraycopy(values, 0, newValues, 0, size); 498 values = newValues; 499 } 500 } 501 502 public String name(int value) { 503 for (int i = 0; i < size; ++i) { 504 if (values[i] == value) { 505 return names[i]; 506 } 507 } 508 return null; 509 } 510 511 public int value(String name) { 512 for (int i = 0; i < size; ++i) { 513 if (names[i].equals(name)) { 514 return values[i]; 515 } 516 } 517 return -1; 518 } 519 } 520 521 static class BinaryEntityMap extends ArrayEntityMap { 522 523 public BinaryEntityMap() { 524 } 525 526 public BinaryEntityMap(int growBy) { 527 super(growBy); 528 } 529 530 private int binarySearch(int key) { 532 int low = 0; 533 int high = size - 1; 534 535 while (low <= high) { 536 int mid = (low + high) >> 1; 537 int midVal = values[mid]; 538 539 if (midVal < key) { 540 low = mid + 1; 541 } else if (midVal > key) { 542 high = mid - 1; 543 } else { 544 return mid; } 546 } 547 return -(low + 1); } 549 550 public void add(String name, int value) { 551 ensureCapacity(size + 1); 552 int insertAt = binarySearch(value); 553 if (insertAt > 0) { 554 return; } 556 insertAt = -(insertAt + 1); System.arraycopy(values, insertAt, values, insertAt + 1, size - insertAt); 558 values[insertAt] = value; 559 System.arraycopy(names, insertAt, names, insertAt + 1, size - insertAt); 560 names[insertAt] = name; 561 size++; 562 } 563 564 public String name(int value) { 565 int index = binarySearch(value); 566 if (index < 0) { 567 return null; 568 } 569 return names[index]; 570 } 571 } 572 573 EntityMap map = new Entities.LookupEntityMap(); 575 576 public void addEntities(String [][] entityArray) { 577 for (int i = 0; i < entityArray.length; ++i) { 578 addEntity(entityArray[i][0], Integer.parseInt(entityArray[i][1])); 579 } 580 } 581 582 public void addEntity(String name, int value) { 583 map.add(name, value); 584 } 585 586 public String entityName(int value) { 587 return map.name(value); 588 } 589 590 591 public int entityValue(String name) { 592 return map.value(name); 593 } 594 595 604 public String escape(String str) { 605 StringBuffer buf = new StringBuffer (str.length() * 2); 607 int i; 608 for (i = 0; i < str.length(); ++i) { 609 char ch = str.charAt(i); 610 String entityName = this.entityName(ch); 611 if (entityName == null) { 612 if (ch > 0x7F) { 613 int intValue = ch; 614 buf.append("&#"); 615 buf.append(intValue); 616 buf.append(';'); 617 } else { 618 buf.append(ch); 619 } 620 } else { 621 buf.append('&'); 622 buf.append(entityName); 623 buf.append(';'); 624 } 625 } 626 return buf.toString(); 627 } 628 629 638 public String unescape(String str) { 639 StringBuffer buf = new StringBuffer (str.length()); 640 int i; 641 for (i = 0; i < str.length(); ++i) { 642 char ch = str.charAt(i); 643 if (ch == '&') { 644 int semi = str.indexOf(';', i + 1); 645 if (semi == -1) { 646 buf.append(ch); 647 continue; 648 } 649 String entityName = str.substring(i + 1, semi); 650 int entityValue; 651 if (entityName.length() == 0) { 652 entityValue = -1; 653 } else if (entityName.charAt(0) == '#') { 654 if (entityName.length() == 1) { 655 entityValue = -1; 656 } else { 657 char charAt1 = entityName.charAt(1); 658 try { 659 if (charAt1 == 'x' || charAt1=='X') { 660 entityValue = Integer.valueOf(entityName.substring(2), 16).intValue(); 661 } else { 662 entityValue = Integer.parseInt(entityName.substring(1)); 663 } 664 } catch (NumberFormatException ex) { 665 entityValue = -1; 666 } 667 } 668 } else { 669 entityValue = this.entityValue(entityName); 670 } 671 if (entityValue == -1) { 672 buf.append('&'); 673 buf.append(entityName); 674 buf.append(';'); 675 } else { 676 buf.append((char) (entityValue)); 677 } 678 i = semi; 679 } else { 680 buf.append(ch); 681 } 682 } 683 return buf.toString(); 684 } 685 686 } 687 | Popular Tags |