首页

关于google-gdata源码包的基于StringUtil字符串工具类实现HtmlToText的转换处理

标签:StringUtil,HtmlToText,google-gdata-core,字符串工具类,html转文本     发布时间:2018-05-10   

一、前言

关于googlegdata-core源码包定义com.google.gdata.util.common.base.StringUtil字符串工具类、com.google.gdata.util.common.html.HtmlToText转文本处理类,HtmlToText转文本处理类依赖 StringUtil.unescapeHTML、StringUtil.fixedWidth处理等。

二、代码示例

1.StringUtil类

package com.google.gdata.util.common.base;@b@@b@import java.io.BufferedReader;@b@import java.io.ByteArrayInputStream;@b@import java.io.IOException;@b@import java.io.InputStream;@b@import java.io.InputStreamReader;@b@import java.io.OutputStream;@b@import java.io.StringWriter;@b@import java.io.UnsupportedEncodingException;@b@import java.util.ArrayList;@b@import java.util.Collection;@b@import java.util.Collections;@b@import java.util.HashMap;@b@import java.util.HashSet;@b@import java.util.Iterator;@b@import java.util.LinkedList;@b@import java.util.List;@b@import java.util.Map;@b@import java.util.Map.Entry;@b@import java.util.Set;@b@import java.util.StringTokenizer;@b@import java.util.regex.Matcher;@b@import java.util.regex.Pattern;@b@@b@public class StringUtil@b@{@b@  public static final String EMPTY_STRING = "";@b@  public static final String WHITE_SPACES = " \r\n\t ???";@b@  public static final String LINE_BREAKS = "\r\n";@b@  private static final Pattern htmlTagPattern;@b@  private static final Pattern characterReferencePattern;@b@  private static final Pattern dbSpecPattern;@b@  static Map<String, Character> escapeStrings;@b@  private static final String[] UNSAFE_TAGS;@b@  private static final Set<Character.UnicodeBlock> CJK_BLOCKS;@b@  private static char[] hexChars;@b@@b@  public static String[] split(String str, String delims)@b@  {@b@    return split(str, delims, false);@b@  }@b@@b@  public static String[] split(String str, String delims, boolean trimTokens)@b@  {@b@    StringTokenizer tokenizer = new StringTokenizer(str, delims);@b@    int n = tokenizer.countTokens();@b@    String[] list = new String[n];@b@    for (int i = 0; i < n; ++i)@b@      if (trimTokens)@b@        list[i] = tokenizer.nextToken().trim();@b@      else@b@        list[i] = tokenizer.nextToken();@b@@b@@b@    return list;@b@  }@b@@b@  public static String[] splitAndTrim(String str, String delims)@b@  {@b@    return split(str, delims, true);@b@  }@b@@b@  public static int[] splitInts(String str) throws IllegalArgumentException@b@  {@b@    StringTokenizer tokenizer = new StringTokenizer(str, ",");@b@    int n = tokenizer.countTokens();@b@    int[] list = new int[n];@b@    for (int i = 0; i < n; ++i) {@b@      String token = tokenizer.nextToken();@b@      list[i] = Integer.parseInt(token);@b@    }@b@    return list;@b@  }@b@@b@  public static long[] splitLongs(String str) throws IllegalArgumentException@b@  {@b@    StringTokenizer tokenizer = new StringTokenizer(str, ",");@b@    int n = tokenizer.countTokens();@b@    long[] list = new long[n];@b@    for (int i = 0; i < n; ++i) {@b@      String token = tokenizer.nextToken();@b@      list[i] = Long.parseLong(token);@b@    }@b@    return list;@b@  }@b@@b@  public static String joinInts(int[] tokens, String delimiter)@b@  {@b@    if (tokens == null) return "";@b@    StringBuilder result = new StringBuilder();@b@@b@    for (int i = 0; i < tokens.length; ++i) {@b@      if ((i > 0) && (delimiter != null))@b@        result.append(delimiter);@b@@b@      result.append(String.valueOf(tokens[i]));@b@    }@b@    return result.toString();@b@  }@b@@b@  public static String joinLongs(long[] tokens, String delimiter)@b@  {@b@    if (tokens == null) return "";@b@    StringBuilder result = new StringBuilder();@b@@b@    for (int i = 0; i < tokens.length; ++i) {@b@      if ((i > 0) && (delimiter != null))@b@        result.append(delimiter);@b@@b@      result.append(String.valueOf(tokens[i]));@b@    }@b@    return result.toString();@b@  }@b@@b@  @Deprecated@b@  public static String join(Object[] tokens, String delimiter)@b@  {@b@    if ((tokens == null) || (tokens.length == 0)) return "";@b@    StringBuilder result = new StringBuilder();@b@@b@    for (int i = 0; i < tokens.length; ++i) {@b@      if ((i > 0) && (delimiter != null))@b@        result.append(delimiter);@b@@b@      if (tokens[i] != null)@b@        result.append(tokens[i].toString());@b@    }@b@    return result.toString();@b@  }@b@@b@  @Deprecated@b@  public static String join(Collection tokens, String delimiter)@b@  {@b@    return join(tokens.toArray(), delimiter);@b@  }@b@@b@  @Deprecated@b@  public static String replace(String str, String what, String with)@b@  {@b@    if ((!($assertionsDisabled)) && (what.length() <= 0)) throw new AssertionError();@b@    return str.replace(what, with);@b@  }@b@@b@  public static String fixedWidth(String str, int width)@b@  {@b@    String[] lines = split(str, "\n");@b@    return fixedWidth(lines, width);@b@  }@b@@b@  public static String fixedWidth(String[] lines, int width)@b@  {@b@    StringBuilder formatStr = new StringBuilder();@b@@b@    for (int i = 0; i < lines.length; ++i) {@b@      String[] words;@b@      int j;@b@      int curWidth = 0;@b@      if (i != 0) {@b@        formatStr.append("\n");@b@      }@b@@b@      if (lines[i].length() <= width) {@b@        formatStr.append(lines[i]);@b@      }@b@      else {@b@        words = splitAndTrim(lines[i], " \r\n\t ???");@b@        for (j = 0; j < words.length; ++j)@b@          if ((curWidth == 0) || (curWidth + words[j].length() < width))@b@          {@b@            if (curWidth != 0) {@b@              formatStr.append(" ");@b@              ++curWidth;@b@            }@b@            curWidth += words[j].length();@b@            formatStr.append(words[j]);@b@          } else {@b@            formatStr.append("\n");@b@            curWidth = words[j].length();@b@            formatStr.append(words[j]);@b@          }@b@      }@b@    }@b@@b@    return formatStr.toString();@b@  }@b@@b@  public static String insertBreakingWhitespace(int lineLen, String original)@b@  {@b@    if ((original == null) || (lineLen <= 0)) throw new IllegalArgumentException();@b@@b@    int length = original.length();@b@    if (length <= lineLen)@b@    {@b@      return original; }@b@    int currPos = 0;@b@    StringBuilder retval = new StringBuilder();@b@    while (length - currPos > lineLen) {@b@      retval.append(original.substring(currPos, currPos + lineLen));@b@      currPos += lineLen;@b@      retval.append(" ");@b@    }@b@    retval.append(original.substring(currPos, length));@b@    return retval.toString();@b@  }@b@@b@  public static String indent(String iString, int iIndentDepth)@b@  {@b@    StringBuilder spacer = new StringBuilder();@b@    spacer.append("\n");@b@    for (int i = 0; i < iIndentDepth; ++i)@b@      spacer.append("  ");@b@@b@    return replace(iString, "\n", spacer.toString());@b@  }@b@@b@  @Deprecated@b@  public static String megastrip(String str, boolean left, boolean right, String what)@b@  {@b@    if (str == null) {@b@      return null;@b@    }@b@@b@    int limitLeft = 0;@b@    int limitRight = str.length() - 1;@b@@b@    while ((left) && (limitLeft <= limitRight) && (what.indexOf(str.charAt(limitLeft)) >= 0)) {@b@      ++limitLeft;@b@    }@b@@b@    while ((right) && (limitRight >= limitLeft) && (what.indexOf(str.charAt(limitRight)) >= 0))@b@      --limitRight;@b@@b@    return str.substring(limitLeft, limitRight + 1);@b@  }@b@@b@  @Deprecated@b@  public static String lstrip(String str)@b@  {@b@    return ((str == null) ? null : CharMatcher.LEGACY_WHITESPACE.trimLeadingFrom(str));@b@  }@b@@b@  @Deprecated@b@  public static String rstrip(String str)@b@  {@b@    return ((str == null) ? null : CharMatcher.LEGACY_WHITESPACE.trimTrailingFrom(str));@b@  }@b@@b@  public static String strip(String str)@b@  {@b@    return megastrip(str, true, true, " \r\n\t ???");@b@  }@b@@b@  public static String stripAndCollapse(String str)@b@  {@b@    return collapseWhitespace(strip(str));@b@  }@b@@b@  public static String stripPrefix(String str, String prefix)@b@  {@b@    return ((str.startsWith(prefix)) ? str.substring(prefix.length()) : null);@b@  }@b@@b@  public static String stripPrefixIgnoreCase(String str, String prefix)@b@  {@b@    if ((str.length() >= prefix.length()) && (str.substring(0, prefix.length()).equalsIgnoreCase(prefix)))@b@    {@b@      return str.substring(prefix.length());@b@    }@b@@b@    return null;@b@  }@b@@b@  public static String stripNonDigits(String str)@b@  {@b@    StringBuffer result = new StringBuffer(str.length());@b@    char[] arr$ = str.toCharArray(); int len$ = arr$.length; for (int i$ = 0; i$ < len$; ++i$) { char candidate = arr$[i$];@b@      if (Character.isDigit(candidate))@b@        result.append(candidate);@b@    }@b@@b@    return result.toString();@b@  }@b@@b@  public static int numSharedChars(String str, String chars)@b@  {@b@    if ((str == null) || (chars == null)) {@b@      return 0;@b@    }@b@@b@    int total = 0; int pos = -1;@b@    while ((pos = indexOfChars(str, chars, pos + 1)) != -1) {@b@      ++total;@b@    }@b@@b@    return total;@b@  }@b@@b@  public static int indexOfChars(String str, String chars, int fromIndex)@b@  {@b@    int len = str.length();@b@@b@    for (int pos = fromIndex; pos < len; ++pos) {@b@      if (chars.indexOf(str.charAt(pos)) >= 0)@b@        return pos;@b@@b@    }@b@@b@    return -1;@b@  }@b@@b@  public static int indexOfChars(String str, String chars)@b@  {@b@    return indexOfChars(str, chars, 0);@b@  }@b@@b@  public static int lastIndexNotOf(String str, String chars, int fromIndex)@b@  {@b@    fromIndex = Math.min(fromIndex, str.length() - 1);@b@@b@    for (int pos = fromIndex; pos >= 0; --pos) {@b@      if (chars.indexOf(str.charAt(pos)) < 0)@b@        return pos;@b@@b@    }@b@@b@    return -1;@b@  }@b@@b@  public static String replaceChars(String str, String oldchars, char newchar)@b@  {@b@    int pos = indexOfChars(str, oldchars);@b@    if (pos == -1) {@b@      return str;@b@    }@b@@b@    StringBuilder buf = new StringBuilder(str);@b@    do {@b@      buf.setCharAt(pos, newchar);@b@      pos = indexOfChars(str, oldchars, pos + 1); }@b@    while (pos != -1);@b@@b@    return buf.toString();@b@  }@b@@b@  public static String removeChars(String str, String oldchars)@b@  {@b@    int pos = indexOfChars(str, oldchars);@b@    if (pos == -1) {@b@      return str;@b@    }@b@@b@    StringBuilder buf = new StringBuilder();@b@    int start = 0;@b@    do {@b@      buf.append(str.substring(start, pos));@b@      start = pos + 1;@b@      pos = indexOfChars(str, oldchars, start); }@b@    while (pos != -1);@b@@b@    if (start < str.length())@b@      buf.append(str.substring(start));@b@@b@    return buf.toString();@b@  }@b@@b@  public static String retainAllChars(String str, String retainChars)@b@  {@b@    int pos = indexOfChars(str, retainChars);@b@    if (pos == -1)@b@      return "";@b@@b@    StringBuilder buf = new StringBuilder();@b@    do {@b@      buf.append(str.charAt(pos));@b@      pos = indexOfChars(str, retainChars, pos + 1); }@b@    while (pos != -1);@b@    return buf.toString();@b@  }@b@@b@  public static String replaceSmartQuotes(String str)@b@  {@b@    str = replaceChars(str, "??‘’", '\'');@b@    str = replaceChars(str, "??“”", '"');@b@    return str;@b@  }@b@@b@  public static byte[] hexToBytes(String str)@b@  {@b@    byte[] bytes = new byte[(str.length() + 1) / 2];@b@    if (str.length() == 0)@b@      return bytes;@b@@b@    bytes[0] = 0;@b@    int nibbleIdx = str.length() % 2;@b@    for (int i = 0; i < str.length(); ++i) {@b@      char c = str.charAt(i);@b@      if (!(isHex(c)))@b@        throw new IllegalArgumentException("string contains non-hex chars");@b@@b@      if (nibbleIdx % 2 == 0) {@b@        bytes[(nibbleIdx >> 1)] = (byte)(hexValue(c) << 4);@b@      } else {@b@        int tmp92_91 = (nibbleIdx >> 1);@b@        byte[] tmp92_88 = bytes; tmp92_88[tmp92_91] = (byte)(tmp92_88[tmp92_91] + (byte)hexValue(c));@b@      }@b@      ++nibbleIdx;@b@    }@b@    return bytes;@b@  }@b@@b@  public static String convertEOLToLF(String input)@b@  {@b@    StringBuilder res = new StringBuilder(input.length());@b@    char[] s = input.toCharArray();@b@    int from = 0;@b@    int end = s.length;@b@    for (int i = 0; i < end; ++i)@b@      if (s[i] == '\r') {@b@        res.append(s, from, i - from);@b@        res.append('\n');@b@        if ((i + 1 < end) && (s[(i + 1)] == '\n')) {@b@          ++i;@b@        }@b@@b@        from = i + 1;@b@      }@b@@b@@b@    if (from == 0) {@b@      return input;@b@    }@b@@b@    res.append(s, from, end - from);@b@    return res.toString();@b@  }@b@@b@  @Deprecated@b@  public static String convertEOLToCRLF(String input) {@b@    return input.replaceAll("(\r\n|\r|\n)", "\r\n");@b@  }@b@@b@  public static String padLeft(String s, int len, char pad_ch)@b@  {@b@    if (s.length() >= len)@b@      return s;@b@@b@    StringBuilder sb = new StringBuilder();@b@    int n = len - s.length();@b@    for (int i = 0; i < n; ++i)@b@      sb.append(pad_ch);@b@@b@    sb.append(s);@b@    return sb.toString();@b@  }@b@@b@  public static String padRight(String s, int len, char pad_ch)@b@  {@b@    if (s.length() >= len)@b@      return s;@b@@b@    StringBuilder sb = new StringBuilder();@b@    int n = len - s.length();@b@    sb.append(s);@b@    for (int i = 0; i < n; ++i)@b@      sb.append(pad_ch);@b@@b@    return sb.toString();@b@  }@b@@b@  public static String maskLeft(String s, int len, char mask_ch)@b@  {@b@    if (len <= 0)@b@      return s;@b@@b@    len = Math.min(len, s.length());@b@    StringBuilder sb = new StringBuilder();@b@    for (int i = 0; i < len; ++i)@b@      sb.append(mask_ch);@b@@b@    sb.append(s.substring(len));@b@    return sb.toString();@b@  }@b@@b@  public static String maskRight(String s, int len, char mask_ch)@b@  {@b@    if (len <= 0)@b@      return s;@b@@b@    len = Math.min(len, s.length());@b@    StringBuilder sb = new StringBuilder();@b@    sb.append(s.substring(0, s.length() - len));@b@    for (int i = 0; i < len; ++i)@b@      sb.append(mask_ch);@b@@b@    return sb.toString();@b@  }@b@@b@  private static boolean isOctal(char c) {@b@    return ((c >= '0') && (c <= '7'));@b@  }@b@@b@  private static boolean isHex(char c) {@b@    return (((c >= '0') && (c <= '9')) || ((c >= 'a') && (c <= 'f')) || ((c >= 'A') && (c <= 'F')));@b@  }@b@@b@  private static int hexValue(char c)@b@  {@b@    if ((c >= '0') && (c <= '9'))@b@      return (c - '0');@b@    if ((c >= 'a') && (c <= 'f'))@b@      return (c - 'a' + 10);@b@@b@    return (c - 'A' + 10);@b@  }@b@@b@  public static String unescapeCString(String s)@b@  {@b@    if (s.indexOf(92) < 0)@b@    {@b@      return s;@b@    }@b@@b@    StringBuilder sb = new StringBuilder();@b@    int len = s.length();@b@    for (int i = 0; i < len; ) {@b@      char c = s.charAt(i++);@b@      if ((c == '\\') && (i < len)) {@b@        c = s.charAt(i++);@b@        switch (c) {@b@        case 'a':@b@          c = '\7'; break;@b@        case 'b':@b@          c = '\b'; break;@b@        case 'f':@b@          c = '\f'; break;@b@        case 'n':@b@          c = '\n'; break;@b@        case 'r':@b@          c = '\r'; break;@b@        case 't':@b@          c = '\t'; break;@b@        case 'v':@b@          c = '\11'; break;@b@        case '\\':@b@          c = '\\'; break;@b@        case '?':@b@          c = '?'; break;@b@        case '\'':@b@          c = '\''; break;@b@        case '"':@b@          c = '"'; break;@b@        default:@b@          int v;@b@          if ((c == 'x') && (i < len) && (isHex(s.charAt(i))))@b@          {@b@            v = hexValue(s.charAt(i++));@b@            if ((i < len) && (isHex(s.charAt(i))))@b@              v = v * 16 + hexValue(s.charAt(i++));@b@@b@            c = (char)v;@b@          } else if (isOctal(c))@b@          {@b@            v = c - '0';@b@            if ((i < len) && (isOctal(s.charAt(i))))@b@              v = v * 8 + s.charAt(i++) - '0';@b@@b@            if ((i < len) && (isOctal(s.charAt(i))))@b@              v = v * 8 + s.charAt(i++) - '0';@b@@b@            c = (char)v;@b@          }@b@          else {@b@            sb.append('\\');@b@          }@b@        }@b@@b@      }@b@@b@      sb.append(c);@b@    }@b@    return sb.toString();@b@  }@b@@b@  public static String unescapeMySQLString(String s)@b@    throws IllegalArgumentException@b@  {@b@    char[] chars = s.toCharArray();@b@@b@    if ((chars.length < 2) || (chars[0] != chars[(chars.length - 1)]) || ((chars[0] != '\'') && (chars[0] != '"')))@b@    {@b@      throw new IllegalArgumentException("not a valid MySQL string: " + s);@b@    }@b@@b@    int j = 1;@b@    int f = 0;@b@    for (int i = 1; i < chars.length - 1; ++i)@b@      if (f == 0) {@b@        if (chars[i] == '\\')@b@          f = 1;@b@        else if (chars[i] == chars[0])@b@          f = 2;@b@        else@b@          chars[(j++)] = chars[i];@b@      }@b@      else if (f == 1) {@b@        switch (chars[i]) {@b@        case '0':@b@          chars[(j++)] = '; break;@b@        case '\'':@b@          chars[(j++)] = '\''; break;@b@        case '"':@b@          chars[(j++)] = '"'; break;@b@        case 'b':@b@          chars[(j++)] = '\b'; break;@b@        case 'n':@b@          chars[(j++)] = '\n'; break;@b@        case 'r':@b@          chars[(j++)] = '\r'; break;@b@        case 't':@b@          chars[(j++)] = '\t'; break;@b@        case 'z':@b@          chars[(j++)] = '\26'; break;@b@        case '\\':@b@          chars[(j++)] = '\\'; break;@b@        default:@b@          chars[(j++)] = chars[i];@b@        }@b@@b@        f = 0;@b@      }@b@      else {@b@        if (chars[i] != chars[0])@b@          throw new IllegalArgumentException("not a valid MySQL string: " + s);@b@@b@        chars[(j++)] = chars[0];@b@        f = 0;@b@      }@b@@b@@b@    if (f != 0) {@b@      throw new IllegalArgumentException("not a valid MySQL string: " + s);@b@    }@b@@b@    return new String(chars, 1, j - 1);@b@  }@b@@b@  public static final String unescapeHTML(String s)@b@  {@b@    char[] chars = s.toCharArray();@b@    char[] escaped = new char[chars.length];@b@@b@    int pos = 0;@b@@b@    int i = 0;@b@    while (true) { while (true) { if (i >= chars.length) break label344;@b@        if (chars[i] == '&') break;@b@        escaped[(pos++)] = chars[(i++)];@b@      }@b@@b@      int j = i + 1;@b@      if ((j < chars.length) && (chars[j] == '#')) {@b@        ++j;@b@      }@b@@b@      for (; j < chars.length; ++j)@b@        if (!(Character.isLetterOrDigit(chars[j])))@b@          break;@b@@b@@b@      boolean replaced = false;@b@      if ((j < chars.length) && (chars[j] == ';')) {@b@        if (s.charAt(i + 1) == '#') {@b@          try {@b@            long charcode = 0L;@b@            char ch = s.charAt(i + 2);@b@            if ((ch == 'x') || (ch == 'X')) {@b@              charcode = Long.parseLong(new String(chars, i + 3, j - i - 3), 16);@b@            }@b@            else if (Character.isDigit(ch))@b@              charcode = Long.parseLong(new String(chars, i + 2, j - i - 2));@b@@b@            if ((charcode > 0L) && (charcode < 65536L)) {@b@              escaped[(pos++)] = (char)(int)charcode;@b@              replaced = true;@b@            }@b@          }@b@          catch (NumberFormatException ex) {@b@          }@b@        }@b@        else {@b@          String key = new String(chars, i, j - i + 1);@b@          Character repl = (Character)escapeStrings.get(key);@b@          if (repl != null) {@b@            escaped[(pos++)] = repl.charValue();@b@            replaced = true;@b@          }@b@        }@b@        ++j;@b@      }@b@@b@      if (!(replaced))@b@      {@b@        System.arraycopy(chars, i, escaped, pos, j - i);@b@        pos += j - i;@b@      }@b@      i = j;@b@    }@b@    label344: return new String(escaped, 0, pos);@b@  }@b@@b@  public static String stripHtmlTags(String string)@b@  {@b@    if ((string == null) || ("".equals(string)))@b@      return string;@b@@b@    return htmlTagPattern.matcher(string).replaceAll("");@b@  }@b@@b@  public static String pythonEscape(String s)@b@  {@b@    StringBuilder sb = new StringBuilder();@b@    for (int i = 0; i < s.length(); ++i) {@b@      char c = s.charAt(i);@b@      switch (c) {@b@      case '\n':@b@        sb.append("\\n"); break;@b@      case '\r':@b@        sb.append("\\r"); break;@b@      case '\t':@b@        sb.append("\\t"); break;@b@      case '\\':@b@        sb.append("\\\\"); break;@b@      case '"':@b@        sb.append("\\\""); break;@b@      case '\'':@b@        sb.append("\\'"); break;@b@      default:@b@        sb.append(c);@b@      }@b@    }@b@    return sb.toString();@b@  }@b@@b@  public static String javaScriptEscape(String s)@b@  {@b@    return javaScriptEscapeHelper(s, false);@b@  }@b@@b@  public static String javaScriptEscapeToAscii(String s)@b@  {@b@    return javaScriptEscapeHelper(s, true);@b@  }@b@@b@  private static String javaScriptEscapeHelper(String s, boolean escapeToAscii)@b@  {@b@    StringBuilder sb = new StringBuilder(s.length() * 9 / 8);@b@    for (int i = 0; i < s.length(); ++i) {@b@      char c = s.charAt(i);@b@      switch (c) {@b@      case '\n':@b@        sb.append("\\n"); break;@b@      case '\r':@b@        sb.append("\\r"); break;@b@      case '\t':@b@        sb.append("\\t"); break;@b@      case '\\':@b@        sb.append("\\\\"); break;@b@      case '"':@b@        sb.append("\\\""); break;@b@      case '\'':@b@        sb.append("\\'"); break;@b@      case '=':@b@        appendHexJavaScriptRepresentation(sb, c); break;@b@      case '/':@b@      case '<':@b@        boolean isUnsafe = false;@b@        String[] arr$ = UNSAFE_TAGS; int len$ = arr$.length; for (int i$ = 0; i$ < len$; ++i$) { String tag = arr$[i$];@b@          if (s.regionMatches(true, i + 1, tag, 0, tag.length())) {@b@            isUnsafe = true;@b@            break;@b@          }@b@        }@b@        if (isUnsafe)@b@          appendHexJavaScriptRepresentation(sb, c);@b@        else@b@          sb.append(c);@b@@b@        break;@b@      case '>':@b@        if ((sb.length() > 0) && (sb.charAt(sb.length() - 1) == '-'))@b@          sb.append('\\');@b@@b@        sb.append(c);@b@        break;@b@      case '?':@b@        sb.append("\\u2028"); break;@b@      case '?':@b@        sb.append("\\u2029"); break;@b@      default:@b@        if ((c >= 128) && (escapeToAscii))@b@          appendHexJavaScriptRepresentation(sb, c);@b@        else@b@          sb.append(c);@b@      }@b@    }@b@@b@    return sb.toString();@b@  }@b@@b@  public static void appendHexJavaScriptRepresentation(StringBuilder sb, char c)@b@  {@b@    sb.append("\\u");@b@    String val = Integer.toHexString(c);@b@    for (int j = val.length(); j < 4; ++j)@b@      sb.append('0');@b@@b@    sb.append(val);@b@  }@b@@b@  public static String javaScriptUnescape(String s)@b@  {@b@    StringBuilder sb = new StringBuilder(s.length());@b@    for (int i = 0; i < s.length(); ) {@b@      char c = s.charAt(i);@b@      if (c == '\\') {@b@        i = javaScriptUnescapeHelper(s, i + 1, sb);@b@      } else {@b@        sb.append(c);@b@        ++i;@b@      }@b@    }@b@    return sb.toString();@b@  }@b@@b@  private static int javaScriptUnescapeHelper(String s, int i, StringBuilder sb)@b@  {@b@    if (i >= s.length()) {@b@      throw new IllegalArgumentException("End-of-string after escape character in [" + s + "]");@b@    }@b@@b@    char c = s.charAt(i++);@b@    switch (c) { case 'n':@b@      sb.append('\n'); break;@b@    case 'r':@b@      sb.append('\r'); break;@b@    case 't':@b@      sb.append('\t'); break;@b@    case '"':@b@    case '\'':@b@    case '>':@b@    case '\\':@b@      sb.append(c);@b@      break;@b@    case 'u':@b@      String hexCode;@b@      int unicodeValue;@b@      try { hexCode = s.substring(i, i + 4);@b@      } catch (IndexOutOfBoundsException ioobe) {@b@        throw new IllegalArgumentException("Invalid unicode sequence [" + s.substring(i) + "] at index " + i + " in [" + s + "]");@b@      }@b@@b@      try@b@      {@b@        unicodeValue = Integer.parseInt(hexCode, 16);@b@      } catch (NumberFormatException nfe) {@b@        throw new IllegalArgumentException("Invalid unicode sequence [" + hexCode + "] at index " + i + " in [" + s + "]");@b@      }@b@@b@      sb.append((char)unicodeValue);@b@      i += 4;@b@      break;@b@    default:@b@      throw new IllegalArgumentException("Unknown escape code [" + c + "] at index " + i + " in [" + s + "]");@b@    }@b@@b@    return i;@b@  }@b@@b@  public static String xmlContentEscape(String s)@b@  {@b@    StringBuilder sb = new StringBuilder();@b@    for (int i = 0; i < s.length(); ++i) {@b@      char c = s.charAt(i);@b@      switch (c) {@b@      case '&':@b@        sb.append("&amp;"); break;@b@      case '<':@b@        sb.append("&lt;"); break;@b@      case '\0':@b@      case '\1':@b@      case '\2':@b@      case '\3':@b@      case '\4':@b@      case '\5':@b@      case '\6':@b@      case '\7':@b@      case '\b':@b@      case '\11':@b@      case '\f':@b@      case '\14':@b@      case '\15':@b@      case '\16':@b@      case '\17':@b@      case '\18':@b@      case '\19':@b@      case '\20':@b@      case '\21':@b@      case '\22':@b@      case '\23':@b@      case '\24':@b@      case '\25':@b@      case '\26':@b@      case '\27':@b@      case '\28':@b@      case '\29':@b@      case '\30':@b@      case '\31':@b@        break;@b@      case '\t':@b@      case '\n':@b@      case '\r':@b@      case ' ':@b@      case '!':@b@      case '"':@b@      case '#':@b@      case '$':@b@      case '%':@b@      case '\'':@b@      case '(':@b@      case ')':@b@      case '*':@b@      case '+':@b@      case ',':@b@      case '-':@b@      case '.':@b@      case '/':@b@      case '0':@b@      case '1':@b@      case '2':@b@      case '3':@b@      case '4':@b@      case '5':@b@      case '6':@b@      case '7':@b@      case '8':@b@      case '9':@b@      case ':':@b@      case ';':@b@      default:@b@        sb.append(c);@b@      }@b@    }@b@    return sb.toString();@b@  }@b@@b@  public static String xmlSingleQuotedEscape(String s)@b@  {@b@    StringBuilder sb = new StringBuilder();@b@    for (int i = 0; i < s.length(); ++i) {@b@      char c = s.charAt(i);@b@      switch (c) {@b@      case '\'':@b@        sb.append("&quot;"); break;@b@      case '&':@b@        sb.append("&amp;"); break;@b@      case '<':@b@        sb.append("&lt;"); break;@b@      case '\n':@b@        sb.append("&#xA;"); break;@b@      case '\0':@b@      case '\1':@b@      case '\2':@b@      case '\3':@b@      case '\4':@b@      case '\5':@b@      case '\6':@b@      case '\7':@b@      case '\b':@b@      case '\11':@b@      case '\f':@b@      case '\14':@b@      case '\15':@b@      case '\16':@b@      case '\17':@b@      case '\18':@b@      case '\19':@b@      case '\20':@b@      case '\21':@b@      case '\22':@b@      case '\23':@b@      case '\24':@b@      case '\25':@b@      case '\26':@b@      case '\27':@b@      case '\28':@b@      case '\29':@b@      case '\30':@b@      case '\31':@b@        break;@b@      case '\t':@b@      case '\r':@b@      case ' ':@b@      case '!':@b@      case '"':@b@      case '#':@b@      case '$':@b@      case '%':@b@      case '(':@b@      case ')':@b@      case '*':@b@      case '+':@b@      case ',':@b@      case '-':@b@      case '.':@b@      case '/':@b@      case '0':@b@      case '1':@b@      case '2':@b@      case '3':@b@      case '4':@b@      case '5':@b@      case '6':@b@      case '7':@b@      case '8':@b@      case '9':@b@      case ':':@b@      case ';':@b@      default:@b@        sb.append(c);@b@      }@b@    }@b@    return sb.toString();@b@  }@b@@b@  public static String javaEscape(String s)@b@  {@b@    StringBuilder sb = new StringBuilder();@b@    for (int i = 0; i < s.length(); ++i) {@b@      char c = s.charAt(i);@b@      switch (c) {@b@      case '\n':@b@        sb.append("\\n"); break;@b@      case '\r':@b@        sb.append("\\r"); break;@b@      case '\t':@b@        sb.append("\\t"); break;@b@      case '\\':@b@        sb.append("\\\\"); break;@b@      case '"':@b@        sb.append("\\\""); break;@b@      case '&':@b@        sb.append("&amp;"); break;@b@      case '<':@b@        sb.append("&lt;"); break;@b@      case '>':@b@        sb.append("&gt;"); break;@b@      case '\'':@b@        sb.append("\\'"); break;@b@      default:@b@        sb.append(c);@b@      }@b@    }@b@    return sb.toString();@b@  }@b@@b@  public static String javaEscapeWithinAttribute(String s)@b@  {@b@    StringBuilder sb = new StringBuilder();@b@    for (int i = 0; i < s.length(); ++i) {@b@      char c = s.charAt(i);@b@      switch (c) {@b@      case '\n':@b@        sb.append("\\n"); break;@b@      case '\r':@b@        sb.append("\\r"); break;@b@      case '\t':@b@        sb.append("\\t"); break;@b@      case '\\':@b@        sb.append("\\\\"); break;@b@      case '"':@b@        sb.append("&quot;"); break;@b@      case '&':@b@        sb.append("&amp;"); break;@b@      case '<':@b@        sb.append("&lt;"); break;@b@      case '>':@b@        sb.append("&gt;"); break;@b@      case '\'':@b@        sb.append("\\'"); break;@b@      default:@b@        sb.append(c);@b@      }@b@    }@b@    return sb.toString();@b@  }@b@@b@  public static String xmlEscape(String s)@b@  {@b@    StringBuilder sb = new StringBuilder();@b@    for (int i = 0; i < s.length(); ++i) {@b@      char ch = s.charAt(i);@b@      switch (ch)@b@      {@b@      case '"':@b@        sb.append("&quot;");@b@        break;@b@      case '&':@b@        sb.append("&amp;");@b@        break;@b@      case '\'':@b@        sb.append("&apos;");@b@        break;@b@      case '<':@b@        sb.append("&lt;");@b@        break;@b@      case '>':@b@        sb.append("&gt;");@b@        break;@b@      case '\n':@b@        sb.append("&#xA;");@b@        break;@b@      case '\r':@b@        sb.append("&#xD;");@b@        break;@b@      case '\t':@b@        sb.append("&#x9;");@b@        break;@b@      case '\0':@b@        break;@b@      default:@b@        sb.append(ch);@b@      }@b@    }@b@@b@    return sb.toString();@b@  }@b@@b@  public static String htmlEscape(String s)@b@  {@b@    StringBuilder sb = null;@b@@b@    int start = 0;@b@    for (int i = 0; i < s.length(); ++i) {@b@      String replacement;@b@      switch (s.charAt(i))@b@      {@b@      case '"':@b@        replacement = "&quot;";@b@        break;@b@      case '&':@b@        replacement = "&amp;";@b@        break;@b@      case '<':@b@        replacement = "&lt;";@b@        break;@b@      case '>':@b@        replacement = "&gt;";@b@        break;@b@      default:@b@        replacement = null;@b@      }@b@@b@      if (replacement != null) {@b@        if (sb == null)@b@        {@b@          sb = new StringBuilder(s.length() + replacement.length() - 1);@b@        }@b@        if (i > start)@b@        {@b@          sb.append(s.substring(start, i));@b@        }@b@        sb.append(replacement);@b@        start = i + 1;@b@      }@b@    }@b@@b@    if (start > 0) {@b@      sb.append(s.substring(start));@b@    }@b@@b@    if (sb != null)@b@      return sb.toString();@b@@b@    return s;@b@  }@b@@b@  public static String regexEscape(String s)@b@  {@b@    StringBuilder sb = new StringBuilder();@b@@b@    for (int i = 0; i < s.length(); ++i) {@b@      char c = s.charAt(i);@b@@b@      if ("()|*+?.{}[]$^\\".indexOf(c) != -1) {@b@        sb.append('\\');@b@        sb.append(c);@b@      }@b@      else {@b@        sb.append(c);@b@      }@b@    }@b@@b@    return sb.toString();@b@  }@b@@b@  public static String javaUtilRegexEscape(String s)@b@  {@b@    if (s.indexOf("\\E") == -1) {@b@      return "\\Q" + s + "\\E";@b@    }@b@@b@    StringBuilder sb = new StringBuilder();@b@    for (int i = 0; i < s.length(); ++i) {@b@      sb.append('\\');@b@      sb.append(s.charAt(i));@b@    }@b@@b@    return sb.toString();@b@  }@b@@b@  public static String regexReplacementEscape(String s)@b@  {@b@    StringBuilder sb = null;@b@@b@    int i = 0; for (int n = s.length(); i < n; ++i) {@b@      char c = s.charAt(i);@b@@b@      switch (c)@b@      {@b@      case '$':@b@      case '\\':@b@        if (sb == null)@b@        {@b@          sb = new StringBuilder(s.substring(0, i));@b@        }@b@        sb.append('\\');@b@      }@b@      if (sb != null) {@b@        sb.append(c);@b@      }@b@@b@    }@b@@b@    return ((sb == null) ? s : sb.toString());@b@  }@b@@b@  public static String cropBetween(String in, char limit)@b@  {@b@    return cropBetween(in, String.valueOf(new char[] { limit }));@b@  }@b@@b@  public static String cropBetween(String in, String limit)@b@  {@b@    StringBuilder out = new StringBuilder();@b@    int lastPos = 0;@b@    int lenLimit = limit.length();@b@    boolean modeAdd = true;@b@    int pos = -1;@b@    while ((pos = in.indexOf(limit, lastPos)) >= 0) {@b@      if (modeAdd)@b@        out.append(in.substring(lastPos, pos));@b@@b@      modeAdd = !(modeAdd);@b@      lastPos = pos + lenLimit;@b@    }@b@@b@    if (modeAdd) {@b@      out.append(in.substring(lastPos));@b@    }@b@@b@    return out.toString();@b@  }@b@@b@  public static LinkedList<String> string2List(String in, String delimiter, boolean doStrip)@b@  {@b@    if (in == null) {@b@      return null;@b@    }@b@@b@    LinkedList out = new LinkedList();@b@    string2Collection(in, delimiter, doStrip, out);@b@    return out;@b@  }@b@@b@  public static Set string2Set(String in, String delimiter, boolean doStrip)@b@  {@b@    if (in == null) {@b@      return null;@b@    }@b@@b@    HashSet out = new HashSet();@b@    string2Collection(in, delimiter, doStrip, out);@b@    return out;@b@  }@b@@b@  public static Collection<String> string2Collection(String in, String delimiter, boolean doStrip, Collection<String> collection)@b@  {@b@    if (in == null)@b@      return null;@b@@b@    if (collection == null)@b@      collection = new ArrayList();@b@@b@    if ((delimiter == null) || (delimiter.length() == 0)) {@b@      collection.add(in);@b@      return collection;@b@    }@b@@b@    int fromIndex = 0;@b@@b@    while ((pos = in.indexOf(delimiter, fromIndex)) >= 0) {@b@      int pos;@b@      interim = in.substring(fromIndex, pos);@b@      if (doStrip)@b@        interim = strip(interim);@b@@b@      if ((!(doStrip)) || (interim.length() > 0)) {@b@        collection.add(interim);@b@      }@b@@b@      fromIndex = pos + delimiter.length();@b@    }@b@@b@    String interim = in.substring(fromIndex);@b@    if (doStrip)@b@      interim = strip(interim);@b@@b@    if ((!(doStrip)) || (interim.length() > 0)) {@b@      collection.add(interim);@b@    }@b@@b@    return collection;@b@  }@b@@b@  @Deprecated@b@  public static String list2String(Collection<?> in, String separator)@b@  {@b@    return Collection2String(in, separator);@b@  }@b@@b@  @Deprecated@b@  public static String Collection2String(Collection<?> in, String separator)@b@  {@b@    if (in == null)@b@      return null;@b@@b@    return Iterator2String(in.iterator(), separator);@b@  }@b@@b@  @Deprecated@b@  public static String Iterator2String(Iterator<?> it, String separator)@b@  {@b@    if (it == null) {@b@      return null;@b@    }@b@@b@    StringBuilder out = new StringBuilder();@b@    while (it.hasNext()) {@b@      if (out.length() > 0)@b@        out.append(separator);@b@@b@      out.append(it.next().toString());@b@    }@b@@b@    return out.toString();@b@  }@b@@b@  public static HashMap<String, String> string2Map(String in, String delimEntry, String delimKey, boolean doStripEntry)@b@  {@b@    if (in == null) {@b@      return null;@b@    }@b@@b@    HashMap out = new HashMap();@b@@b@    if ((isEmpty(delimEntry)) || (isEmpty(delimKey))) {@b@      out.put(strip(in), "");@b@      return out;@b@    }@b@@b@    Iterator it = string2List(in, delimEntry, false).iterator();@b@    int len = delimKey.length();@b@    while (it.hasNext()) {@b@      String entry = (String)it.next();@b@      int pos = entry.indexOf(delimKey);@b@      if (pos > 0) {@b@        String value = entry.substring(pos + len);@b@        if (doStripEntry)@b@          value = strip(value);@b@@b@        out.put(strip(entry.substring(0, pos)), value);@b@      } else {@b@        out.put(strip(entry), "");@b@      }@b@    }@b@@b@    return out;@b@  }@b@@b@  public static <K, V> String map2String(Map<K, V> in, String sepKey, String sepEntry)@b@  {@b@    if (in == null) {@b@      return null;@b@    }@b@@b@    StringBuilder out = new StringBuilder();@b@    Iterator it = in.entrySet().iterator();@b@    while (it.hasNext()) {@b@      if (out.length() > 0)@b@        out.append(sepEntry);@b@@b@      Map.Entry entry = (Map.Entry)it.next();@b@      out.append(entry.getKey() + sepKey + entry.getValue());@b@    }@b@@b@    return out.toString();@b@  }@b@@b@  public static <V> Map lowercaseKeys(Map<String, V> map)@b@  {@b@    Map result = new HashMap(map.size());@b@    for (Iterator it = map.keySet().iterator(); it.hasNext(); ) {@b@      String key = (String)it.next();@b@      if (result.containsKey(key.toLowerCase())) {@b@        throw new IllegalArgumentException("Duplicate string key in map when lower casing");@b@      }@b@@b@      result.put(key.toLowerCase(), map.get(key));@b@    }@b@    return result;@b@  }@b@@b@  public static String collapseWhitespace(String str)@b@  {@b@    return collapse(str, " \r\n\t ???", " ");@b@  }@b@@b@  public static String collapse(String str, String chars, String replacement)@b@  {@b@    if (str == null) {@b@      return null;@b@    }@b@@b@    StringBuilder newStr = new StringBuilder();@b@@b@    boolean prevCharMatched = false;@b@@b@    for (int i = 0; i < str.length(); ++i) {@b@      char c = str.charAt(i);@b@      if (chars.indexOf(c) != -1)@b@      {@b@        if (prevCharMatched)@b@        {@b@          break label77:@b@        }@b@        prevCharMatched = true;@b@        newStr.append(replacement);@b@      }@b@      else {@b@        prevCharMatched = false;@b@        newStr.append(c);@b@      }@b@    }@b@@b@    label77: return newStr.toString();@b@  }@b@@b@  public static String stream2String(InputStream is, int maxLength)@b@    throws IOException@b@  {@b@    byte[] buffer = new byte[4096];@b@    StringWriter sw = new StringWriter();@b@    int totalRead = 0;@b@    int read = 0;@b@    do@b@    {@b@      sw.write(new String(buffer, 0, read));@b@      totalRead += read;@b@      read = is.read(buffer, 0, buffer.length); }@b@    while ((((-1 == maxLength) || (totalRead < maxLength))) && (read != -1));@b@@b@    return sw.toString();@b@  }@b@@b@  public static String[] parseDelimitedList(String list, char delimiter)@b@  {@b@    String delim = "" + delimiter;@b@@b@    StringTokenizer st = new StringTokenizer(list + delim + " ", delim, true);@b@@b@    ArrayList v = new ArrayList();@b@    String lastToken = "";@b@    String word = "";@b@@b@    while (st.hasMoreTokens()) {@b@      String tok = st.nextToken();@b@      if (lastToken != null)@b@        if (tok.equals(delim)) {@b@          word = word + lastToken;@b@          if (lastToken.equals(delim)) tok = null;@b@        } else {@b@          if (!(word.equals(""))) v.add(word);@b@          word = "";@b@        }@b@@b@      lastToken = tok;@b@    }@b@@b@    return ((String[])v.toArray(new String[0]));@b@  }@b@@b@  public static boolean isEmpty(String s)@b@  {@b@    return (makeSafe(s).length() == 0);@b@  }@b@@b@  public static boolean isEmptyOrWhitespace(String s)@b@  {@b@    s = makeSafe(s);@b@    int i = 0; for (int n = s.length(); i < n; ++i)@b@      if (!(Character.isWhitespace(s.charAt(i))))@b@        return false;@b@@b@@b@    return true;@b@  }@b@@b@  public static String makeSafe(String s)@b@  {@b@    return ((s == null) ? "" : s);@b@  }@b@@b@  public static String toNullIfEmpty(String s)@b@  {@b@    return ((isEmpty(s)) ? null : s);@b@  }@b@@b@  public static String toNullIfEmptyOrWhitespace(String s)@b@  {@b@    return ((isEmptyOrWhitespace(s)) ? null : s);@b@  }@b@@b@  public static String arrayMap2String(Map<String, String[]> map, String keyValueDelim, String entryDelim)@b@  {@b@    Set entrySet = map.entrySet();@b@    Iterator itor = entrySet.iterator();@b@    StringWriter sw = new StringWriter();@b@    while (itor.hasNext()) {@b@      Map.Entry entry = (Map.Entry)itor.next();@b@      String key = (String)entry.getKey();@b@      String[] values = (String[])entry.getValue();@b@      for (int i = 0; i < values.length; ++i) {@b@        sw.write(((String)entry.getKey()) + keyValueDelim + values[i]);@b@        if (i < values.length - 1)@b@          sw.write(entryDelim);@b@      }@b@@b@      if (itor.hasNext())@b@        sw.write(entryDelim);@b@    }@b@@b@    return sw.toString();@b@  }@b@@b@  public static boolean equals(String s1, String s2)@b@  {@b@    if (s1 == s2)@b@      return true;@b@@b@    if ((s1 != null) && @b@      (s2 != null)) {@b@      return s1.equals(s2);@b@    }@b@@b@    return false;@b@  }@b@@b@  public static String lastToken(String s, String delimiter)@b@  {@b@    String[] parts = split(s, delimiter);@b@    return ((parts.length == 0) ? "" : parts[(parts.length - 1)]);@b@  }@b@@b@  public static boolean allAscii(String s)@b@  {@b@    int len = s.length();@b@    for (int i = 0; i < len; ++i)@b@      if ((s.charAt(i) & 0xFF80) != 0)@b@        return false;@b@@b@@b@    return true;@b@  }@b@@b@  public static boolean containsCharRef(String s)@b@  {@b@    return characterReferencePattern.matcher(s).find();@b@  }@b@@b@  public static boolean isHebrew(String s)@b@  {@b@    int len = s.length();@b@    for (int i = 0; i < len; ++i)@b@      if (isHebrew(s.codePointAt(i)))@b@        return true;@b@@b@@b@    return false;@b@  }@b@@b@  public static boolean isHebrew(int codePoint)@b@  {@b@    return Character.UnicodeBlock.HEBREW.equals(Character.UnicodeBlock.of(codePoint));@b@  }@b@@b@  public static boolean isCjk(String s)@b@  {@b@    int len = s.length();@b@    for (int i = 0; i < len; ++i)@b@      if (isCjk(s.codePointAt(i)))@b@        return true;@b@@b@@b@    return false;@b@  }@b@@b@  public static boolean isCjk(char ch)@b@  {@b@    return isCjk(ch);@b@  }@b@@b@  public static boolean isCjk(int codePoint)@b@  {@b@    if ((codePoint & 0xFFFFFF00) == 0) {@b@      return false;@b@    }@b@@b@    return CJK_BLOCKS.contains(Character.UnicodeBlock.of(codePoint));@b@  }@b@@b@  public static String unicodeEscape(String s)@b@  {@b@    if (allAscii(s))@b@      return s;@b@@b@    StringBuilder sb = new StringBuilder(s.length());@b@    int len = s.length();@b@    for (int i = 0; i < len; ++i) {@b@      char ch = s.charAt(i);@b@      if (ch <= '') {@b@        sb.append(ch);@b@      } else {@b@        sb.append("\\u");@b@        String hexString = Integer.toHexString(ch);@b@@b@        int numZerosToPad = 4 - hexString.length();@b@        for (int j = 0; j < numZerosToPad; ++j)@b@          sb.append('0');@b@@b@        sb.append(hexString);@b@      }@b@    }@b@    return sb.toString();@b@  }@b@@b@  public static int displayWidth(String s)@b@  {@b@    int width = 0;@b@    int len = s.length();@b@    for (int i = 0; i < len; ++i)@b@      width += displayWidth(s.charAt(i));@b@@b@    return width;@b@  }@b@@b@  public static int displayWidth(char ch)@b@  {@b@    if ((ch <= 1273) || (ch == 1470) || ((ch >= 1488) && (ch <= 1514)) || (ch == 1523) || (ch == 1524) || ((ch >= 3584) && (ch <= 3711)) || ((ch >= 7680) && (ch <= 8367)) || ((ch >= 8448) && (ch <= 8506)) || ((ch >= 65377) && (ch <= 65500)))@b@    {@b@      return 1;@b@    }@b@    return 2;@b@  }@b@@b@  public static String toString(float[] iArray)@b@  {@b@    if (iArray == null) {@b@      return "NULL";@b@    }@b@@b@    StringBuilder buffer = new StringBuilder();@b@    buffer.append("[");@b@    for (int i = 0; i < iArray.length; ++i) {@b@      buffer.append(iArray[i]);@b@      if (i != iArray.length - 1)@b@        buffer.append(", ");@b@    }@b@@b@    buffer.append("]");@b@    return buffer.toString();@b@  }@b@@b@  public static String toString(long[] iArray)@b@  {@b@    if (iArray == null) {@b@      return "NULL";@b@    }@b@@b@    StringBuilder buffer = new StringBuilder();@b@    buffer.append("[");@b@    for (int i = 0; i < iArray.length; ++i) {@b@      buffer.append(iArray[i]);@b@      if (i != iArray.length - 1)@b@        buffer.append(", ");@b@    }@b@@b@    buffer.append("]");@b@    return buffer.toString();@b@  }@b@@b@  public static String toString(int[] iArray)@b@  {@b@    if (iArray == null) {@b@      return "NULL";@b@    }@b@@b@    StringBuilder buffer = new StringBuilder();@b@    buffer.append("[");@b@    for (int i = 0; i < iArray.length; ++i) {@b@      buffer.append(iArray[i]);@b@      if (i != iArray.length - 1)@b@        buffer.append(", ");@b@    }@b@@b@    buffer.append("]");@b@    return buffer.toString();@b@  }@b@@b@  public static String toString(String[] iArray)@b@  {@b@    if (iArray == null) return "NULL";@b@@b@    StringBuilder buffer = new StringBuilder();@b@    buffer.append("[");@b@    for (int i = 0; i < iArray.length; ++i) {@b@      buffer.append("'").append(iArray[i]).append("'");@b@      if (i != iArray.length - 1)@b@        buffer.append(", ");@b@    }@b@@b@    buffer.append("]");@b@@b@    return buffer.toString();@b@  }@b@@b@  public static String toString(String s)@b@  {@b@    if (s == null)@b@      return "NULL";@b@@b@    return (s.length() + 2) + "'" + s + "'";@b@  }@b@@b@  public static String toString(int[][] iArray)@b@  {@b@    if (iArray == null) {@b@      return "NULL";@b@    }@b@@b@    StringBuilder buffer = new StringBuilder();@b@    buffer.append("[");@b@    for (int i = 0; i < iArray.length; ++i) {@b@      buffer.append("[");@b@      for (int j = 0; j < iArray[i].length; ++j) {@b@        buffer.append(iArray[i][j]);@b@        if (j != iArray[i].length - 1)@b@          buffer.append(", ");@b@      }@b@@b@      buffer.append("]");@b@      if (i != iArray.length - 1)@b@        buffer.append(" ");@b@    }@b@@b@    buffer.append("]");@b@    return buffer.toString();@b@  }@b@@b@  public static String toString(long[][] iArray)@b@  {@b@    if (iArray == null) return "NULL";@b@@b@    StringBuilder buffer = new StringBuilder();@b@    buffer.append("[");@b@    for (int i = 0; i < iArray.length; ++i) {@b@      buffer.append("[");@b@      for (int j = 0; j < iArray[i].length; ++j) {@b@        buffer.append(iArray[i][j]);@b@        if (j != iArray[i].length - 1)@b@          buffer.append(", ");@b@      }@b@@b@      buffer.append("]");@b@      if (i != iArray.length - 1)@b@        buffer.append(" ");@b@    }@b@@b@    buffer.append("]");@b@    return buffer.toString();@b@  }@b@@b@  public static String toString(Object[] obj)@b@  {@b@    if (obj == null) return "NULL";@b@    StringBuilder tmp = new StringBuilder();@b@    tmp.append("[");@b@    for (int i = 0; i < obj.length; ++i) {@b@      tmp.append(obj[i].toString());@b@      if (i != obj.length - 1)@b@        tmp.append(",");@b@    }@b@@b@    tmp.append("]");@b@    return tmp.toString();@b@  }@b@@b@  public static InputStream toUTF8InputStream(String str)@b@  {@b@    InputStream is = null;@b@    try {@b@      is = new ByteArrayInputStream(str.getBytes("UTF-8"));@b@    }@b@    catch (UnsupportedEncodingException e) {@b@      throw new AssertionError();@b@    }@b@    return is;@b@  }@b@@b@  public static void copyStreams(InputStream in, OutputStream out)@b@    throws IOException@b@  {@b@    if ((in == null) || (out == null))@b@      throw new IllegalArgumentException();@b@@b@    byte[] buffer = new byte[4096];@b@@b@    while (-1 != (len = in.read(buffer, 0, buffer.length))) {@b@      int len;@b@      out.write(buffer, 0, len);@b@    }@b@  }@b@@b@  public static String bytesToLatin1(byte[] ba)@b@  {@b@    return bytesToEncoding(ba, "ISO-8859-1");@b@  }@b@@b@  public static String bytesToHexString(byte[] bytes)@b@  {@b@    return bytesToHexString(bytes, null);@b@  }@b@@b@  public static String bytesToHexString(byte[] bytes, Character delimiter)@b@  {@b@    StringBuffer hex = new StringBuffer(bytes.length * 3);@b@@b@    for (int i = 0; i < bytes.length; ++i) {@b@      int nibble1 = bytes[i] >>> 4 & 0xF;@b@      int nibble2 = bytes[i] & 0xF;@b@      if ((i > 0) && (delimiter != null)) hex.append(delimiter.charValue());@b@      hex.append(hexChars[nibble1]);@b@      hex.append(hexChars[nibble2]);@b@    }@b@    return hex.toString();@b@  }@b@@b@  public static byte[] latin1ToBytes(String str)@b@  {@b@    return encodingToBytes(str, "ISO-8859-1");@b@  }@b@@b@  public static String bytesToUtf8(byte[] ba)@b@  {@b@    return bytesToEncoding(ba, "UTF8");@b@  }@b@@b@  public static byte[] utf8ToBytes(String str)@b@  {@b@    return encodingToBytes(str, "UTF8");@b@  }@b@@b@  private static String bytesToEncoding(byte[] ba, String encoding)@b@  {@b@    if (ba == null)@b@      return null;@b@@b@    try@b@    {@b@      return new String(ba, encoding);@b@    } catch (UnsupportedEncodingException e) {@b@      throw new Error(encoding + " not supported! Original exception: " + e);@b@    }@b@  }@b@@b@  public static byte[] encodingToBytes(String str, String encoding)@b@  {@b@    if (str == null)@b@      return null;@b@@b@    try@b@    {@b@      return str.getBytes(encoding);@b@    } catch (UnsupportedEncodingException e) {@b@      throw new Error(encoding + " not supported! Original exception: " + e);@b@    }@b@  }@b@@b@  public static List<String> bytesToStringList(byte[] bytes)@b@  {@b@    List lines = new ArrayList();@b@@b@    if (bytes == null) {@b@      return lines;@b@    }@b@@b@    BufferedReader r = null;@b@    try@b@    {@b@      r = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(bytes), "UTF-8"));@b@    }@b@    catch (UnsupportedEncodingException e)@b@    {@b@      throw new RuntimeException(e);@b@    }@b@    try {@b@      String line;@b@      try {@b@        for (line = r.readLine(); line != null; line = r.readLine())@b@          lines.add(line);@b@      }@b@      finally {@b@        r.close();@b@      }@b@    }@b@    catch (IOException e) {@b@      throw new RuntimeException(e);@b@    }@b@@b@    return lines;@b@  }@b@@b@  public static String toUpperCase(String src)@b@  {@b@    if (src == null)@b@      return null;@b@@b@    return src.toUpperCase();@b@  }@b@@b@  public static String expandShardNames(String dbSpecComponent)@b@    throws IllegalArgumentException, IllegalStateException@b@  {@b@    Matcher matcher = dbSpecPattern.matcher(dbSpecComponent);@b@    if (matcher.find())@b@      try {@b@        String prefix = dbSpecComponent.substring(matcher.start(1), matcher.end(1));@b@@b@        int minShard = Integer.parseInt(dbSpecComponent.substring(matcher.start(2), matcher.end(2)));@b@@b@        int maxShard = Integer.parseInt(dbSpecComponent.substring(matcher.start(3), matcher.end(3)));@b@@b@        String suffix = dbSpecComponent.substring(matcher.start(4), matcher.end(4));@b@@b@        if (minShard > maxShard) {@b@          throw new IllegalArgumentException("Maximum shard must be greater than or equal to the minimum shard");@b@        }@b@@b@        StringBuilder tmp = new StringBuilder();@b@        for (int shard = minShard; shard <= maxShard; ++shard) {@b@          tmp.append(prefix).append(shard).append(suffix);@b@          if (shard != maxShard)@b@            tmp.append(",");@b@        }@b@@b@        return tmp.toString();@b@      } catch (NumberFormatException nfex) {@b@        throw new IllegalArgumentException("Malformed DB specification component: " + dbSpecComponent);@b@      }@b@@b@@b@    return dbSpecComponent;@b@  }@b@@b@  public static String repeat(String sourceString, int factor)@b@  {@b@    if (factor < 1)@b@      return "";@b@@b@    if (factor == 1) {@b@      return sourceString;@b@    }@b@@b@    StringBuilder sb = new StringBuilder(factor * sourceString.length());@b@@b@    while (factor > 0) {@b@      sb.append(sourceString);@b@      --factor;@b@    }@b@@b@    return sb.toString();@b@  }@b@@b@  public static String capitalize(String s)@b@  {@b@    if (s.length() == 0)@b@      return s;@b@    char first = s.charAt(0);@b@    char capitalized = Character.toUpperCase(first);@b@    return capitalized + s.substring(1);@b@  }@b@@b@  static@b@  {@b@    htmlTagPattern = Pattern.compile("</?[a-zA-Z][^>]*>");@b@@b@    characterReferencePattern = Pattern.compile("&#?[a-zA-Z0-9]{1,8};");@b@@b@    dbSpecPattern = Pattern.compile("(.*)\\{(\\d+),(\\d+)\\}(.*)");@b@@b@    escapeStrings = new HashMap(252);@b@@b@    escapeStrings.put("&nbsp;", new Character(160));@b@    escapeStrings.put("&iexcl;", new Character(161));@b@    escapeStrings.put("&cent;", new Character(162));@b@    escapeStrings.put("&pound;", new Character(163));@b@    escapeStrings.put("&curren;", new Character(164));@b@    escapeStrings.put("&yen;", new Character(165));@b@    escapeStrings.put("&brvbar;", new Character(166));@b@    escapeStrings.put("&sect;", new Character(167));@b@    escapeStrings.put("&uml;", new Character(168));@b@    escapeStrings.put("&copy;", new Character(169));@b@    escapeStrings.put("&ordf;", new Character(170));@b@    escapeStrings.put("&laquo;", new Character(171));@b@    escapeStrings.put("&not;", new Character(172));@b@    escapeStrings.put("&shy;", new Character(173));@b@    escapeStrings.put("&reg;", new Character(174));@b@    escapeStrings.put("&macr;", new Character(175));@b@    escapeStrings.put("&deg;", new Character(176));@b@    escapeStrings.put("&plusmn;", new Character(177));@b@    escapeStrings.put("&sup2;", new Character(178));@b@    escapeStrings.put("&sup3;", new Character(179));@b@    escapeStrings.put("&acute;", new Character(180));@b@    escapeStrings.put("&micro;", new Character(181));@b@    escapeStrings.put("&para;", new Character(182));@b@    escapeStrings.put("&middot;", new Character(183));@b@    escapeStrings.put("&cedil;", new Character(184));@b@    escapeStrings.put("&sup1;", new Character(185));@b@    escapeStrings.put("&ordm;", new Character(186));@b@    escapeStrings.put("&raquo;", new Character(187));@b@    escapeStrings.put("&frac14;", new Character(188));@b@    escapeStrings.put("&frac12;", new Character(189));@b@    escapeStrings.put("&frac34;", new Character(190));@b@    escapeStrings.put("&iquest;", new Character(191));@b@    escapeStrings.put("&Agrave;", new Character(192));@b@    escapeStrings.put("&Aacute;", new Character(193));@b@    escapeStrings.put("&Acirc;", new Character(194));@b@    escapeStrings.put("&Atilde;", new Character(195));@b@    escapeStrings.put("&Auml;", new Character(196));@b@    escapeStrings.put("&Aring;", new Character(197));@b@    escapeStrings.put("&AElig;", new Character(198));@b@    escapeStrings.put("&Ccedil;", new Character(199));@b@    escapeStrings.put("&Egrave;", new Character(200));@b@    escapeStrings.put("&Eacute;", new Character(201));@b@    escapeStrings.put("&Ecirc;", new Character(202));@b@    escapeStrings.put("&Euml;", new Character(203));@b@    escapeStrings.put("&Igrave;", new Character(204));@b@    escapeStrings.put("&Iacute;", new Character(205));@b@    escapeStrings.put("&Icirc;", new Character(206));@b@    escapeStrings.put("&Iuml;", new Character(207));@b@    escapeStrings.put("&ETH;", new Character(208));@b@    escapeStrings.put("&Ntilde;", new Character(209));@b@    escapeStrings.put("&Ograve;", new Character(210));@b@    escapeStrings.put("&Oacute;", new Character(211));@b@    escapeStrings.put("&Ocirc;", new Character(212));@b@    escapeStrings.put("&Otilde;", new Character(213));@b@    escapeStrings.put("&Ouml;", new Character(214));@b@    escapeStrings.put("&times;", new Character(215));@b@    escapeStrings.put("&Oslash;", new Character(216));@b@    escapeStrings.put("&Ugrave;", new Character(217));@b@    escapeStrings.put("&Uacute;", new Character(218));@b@    escapeStrings.put("&Ucirc;", new Character(219));@b@    escapeStrings.put("&Uuml;", new Character(220));@b@    escapeStrings.put("&Yacute;", new Character(221));@b@    escapeStrings.put("&THORN;", new Character(222));@b@    escapeStrings.put("&szlig;", new Character(223));@b@    escapeStrings.put("&agrave;", new Character(224));@b@    escapeStrings.put("&aacute;", new Character(225));@b@    escapeStrings.put("&acirc;", new Character(226));@b@    escapeStrings.put("&atilde;", new Character(227));@b@    escapeStrings.put("&auml;", new Character(228));@b@    escapeStrings.put("&aring;", new Character(229));@b@    escapeStrings.put("&aelig;", new Character(230));@b@    escapeStrings.put("&ccedil;", new Character(231));@b@    escapeStrings.put("&egrave;", new Character(232));@b@    escapeStrings.put("&eacute;", new Character(233));@b@    escapeStrings.put("&ecirc;", new Character(234));@b@    escapeStrings.put("&euml;", new Character(235));@b@    escapeStrings.put("&igrave;", new Character(236));@b@    escapeStrings.put("&iacute;", new Character(237));@b@    escapeStrings.put("&icirc;", new Character(238));@b@    escapeStrings.put("&iuml;", new Character(239));@b@    escapeStrings.put("&eth;", new Character(240));@b@    escapeStrings.put("&ntilde;", new Character(241));@b@    escapeStrings.put("&ograve;", new Character(242));@b@    escapeStrings.put("&oacute;", new Character(243));@b@    escapeStrings.put("&ocirc;", new Character(244));@b@    escapeStrings.put("&otilde;", new Character(245));@b@    escapeStrings.put("&ouml;", new Character(246));@b@    escapeStrings.put("&pide;", new Character(247));@b@    escapeStrings.put("&oslash;", new Character(248));@b@    escapeStrings.put("&ugrave;", new Character(249));@b@    escapeStrings.put("&uacute;", new Character(250));@b@    escapeStrings.put("&ucirc;", new Character(251));@b@    escapeStrings.put("&uuml;", new Character(252));@b@    escapeStrings.put("&yacute;", new Character(253));@b@    escapeStrings.put("&thorn;", new Character(254));@b@    escapeStrings.put("&yuml;", new Character(255));@b@    escapeStrings.put("&fnof;", new Character(402));@b@    escapeStrings.put("&Alpha;", new Character(913));@b@    escapeStrings.put("&Beta;", new Character(914));@b@    escapeStrings.put("&Gamma;", new Character(915));@b@    escapeStrings.put("&Delta;", new Character(916));@b@    escapeStrings.put("&Epsilon;", new Character(917));@b@    escapeStrings.put("&Zeta;", new Character(918));@b@    escapeStrings.put("&Eta;", new Character(919));@b@    escapeStrings.put("&Theta;", new Character(920));@b@    escapeStrings.put("&Iota;", new Character(921));@b@    escapeStrings.put("&Kappa;", new Character(922));@b@    escapeStrings.put("&Lambda;", new Character(923));@b@    escapeStrings.put("&Mu;", new Character(924));@b@    escapeStrings.put("&Nu;", new Character(925));@b@    escapeStrings.put("&Xi;", new Character(926));@b@    escapeStrings.put("&Omicron;", new Character(927));@b@    escapeStrings.put("&Pi;", new Character(928));@b@    escapeStrings.put("&Rho;", new Character(929));@b@    escapeStrings.put("&Sigma;", new Character(931));@b@    escapeStrings.put("&Tau;", new Character(932));@b@    escapeStrings.put("&Upsilon;", new Character(933));@b@    escapeStrings.put("&Phi;", new Character(934));@b@    escapeStrings.put("&Chi;", new Character(935));@b@    escapeStrings.put("&Psi;", new Character(936));@b@    escapeStrings.put("&Omega;", new Character(937));@b@    escapeStrings.put("&alpha;", new Character(945));@b@    escapeStrings.put("&beta;", new Character(946));@b@    escapeStrings.put("&gamma;", new Character(947));@b@    escapeStrings.put("&delta;", new Character(948));@b@    escapeStrings.put("&epsilon;", new Character(949));@b@    escapeStrings.put("&zeta;", new Character(950));@b@    escapeStrings.put("&eta;", new Character(951));@b@    escapeStrings.put("&theta;", new Character(952));@b@    escapeStrings.put("&iota;", new Character(953));@b@    escapeStrings.put("&kappa;", new Character(954));@b@    escapeStrings.put("&lambda;", new Character(955));@b@    escapeStrings.put("&mu;", new Character(956));@b@    escapeStrings.put("&nu;", new Character(957));@b@    escapeStrings.put("&xi;", new Character(958));@b@    escapeStrings.put("&omicron;", new Character(959));@b@    escapeStrings.put("&pi;", new Character(960));@b@    escapeStrings.put("&rho;", new Character(961));@b@    escapeStrings.put("&sigmaf;", new Character(962));@b@    escapeStrings.put("&sigma;", new Character(963));@b@    escapeStrings.put("&tau;", new Character(964));@b@    escapeStrings.put("&upsilon;", new Character(965));@b@    escapeStrings.put("&phi;", new Character(966));@b@    escapeStrings.put("&chi;", new Character(967));@b@    escapeStrings.put("&psi;", new Character(968));@b@    escapeStrings.put("&omega;", new Character(969));@b@    escapeStrings.put("&thetasym;", new Character(977));@b@    escapeStrings.put("&upsih;", new Character(978));@b@    escapeStrings.put("&piv;", new Character(982));@b@    escapeStrings.put("&bull;", new Character(8226));@b@    escapeStrings.put("&hellip;", new Character(8230));@b@    escapeStrings.put("&prime;", new Character(8242));@b@    escapeStrings.put("&Prime;", new Character(8243));@b@    escapeStrings.put("&oline;", new Character(8254));@b@    escapeStrings.put("&frasl;", new Character(8260));@b@    escapeStrings.put("&weierp;", new Character(8472));@b@    escapeStrings.put("&image;", new Character(8465));@b@    escapeStrings.put("&real;", new Character(8476));@b@    escapeStrings.put("&trade;", new Character(8482));@b@    escapeStrings.put("&alefsym;", new Character(8501));@b@    escapeStrings.put("&larr;", new Character(8592));@b@    escapeStrings.put("&uarr;", new Character(8593));@b@    escapeStrings.put("&rarr;", new Character(8594));@b@    escapeStrings.put("&darr;", new Character(8595));@b@    escapeStrings.put("&harr;", new Character(8596));@b@    escapeStrings.put("&crarr;", new Character(8629));@b@    escapeStrings.put("&lArr;", new Character(8656));@b@    escapeStrings.put("&uArr;", new Character(8657));@b@    escapeStrings.put("&rArr;", new Character(8658));@b@    escapeStrings.put("&dArr;", new Character(8659));@b@    escapeStrings.put("&hArr;", new Character(8660));@b@    escapeStrings.put("&forall;", new Character(8704));@b@    escapeStrings.put("&part;", new Character(8706));@b@    escapeStrings.put("&exist;", new Character(8707));@b@    escapeStrings.put("&empty;", new Character(8709));@b@    escapeStrings.put("&nabla;", new Character(8711));@b@    escapeStrings.put("&isin;", new Character(8712));@b@    escapeStrings.put("&notin;", new Character(8713));@b@    escapeStrings.put("&ni;", new Character(8715));@b@    escapeStrings.put("&prod;", new Character(8719));@b@    escapeStrings.put("&sum;", new Character(8721));@b@    escapeStrings.put("&minus;", new Character(8722));@b@    escapeStrings.put("&lowast;", new Character(8727));@b@    escapeStrings.put("&radic;", new Character(8730));@b@    escapeStrings.put("&prop;", new Character(8733));@b@    escapeStrings.put("&infin;", new Character(8734));@b@    escapeStrings.put("&ang;", new Character(8736));@b@    escapeStrings.put("&and;", new Character(8743));@b@    escapeStrings.put("&or;", new Character(8744));@b@    escapeStrings.put("&cap;", new Character(8745));@b@    escapeStrings.put("&cup;", new Character(8746));@b@    escapeStrings.put("&int;", new Character(8747));@b@    escapeStrings.put("&there4;", new Character(8756));@b@    escapeStrings.put("&sim;", new Character(8764));@b@    escapeStrings.put("&cong;", new Character(8773));@b@    escapeStrings.put("&asymp;", new Character(8776));@b@    escapeStrings.put("&ne;", new Character(8800));@b@    escapeStrings.put("&equiv;", new Character(8801));@b@    escapeStrings.put("&le;", new Character(8804));@b@    escapeStrings.put("&ge;", new Character(8805));@b@    escapeStrings.put("&sub;", new Character(8834));@b@    escapeStrings.put("&sup;", new Character(8835));@b@    escapeStrings.put("&nsub;", new Character(8836));@b@    escapeStrings.put("&sube;", new Character(8838));@b@    escapeStrings.put("&supe;", new Character(8839));@b@    escapeStrings.put("&oplus;", new Character(8853));@b@    escapeStrings.put("&otimes;", new Character(8855));@b@    escapeStrings.put("&perp;", new Character(8869));@b@    escapeStrings.put("&sdot;", new Character(8901));@b@    escapeStrings.put("&lceil;", new Character(8968));@b@    escapeStrings.put("&rceil;", new Character(8969));@b@    escapeStrings.put("&lfloor;", new Character(8970));@b@    escapeStrings.put("&rfloor;", new Character(8971));@b@    escapeStrings.put("&lang;", new Character(9001));@b@    escapeStrings.put("&rang;", new Character(9002));@b@    escapeStrings.put("&loz;", new Character(9674));@b@    escapeStrings.put("&spades;", new Character(9824));@b@    escapeStrings.put("&clubs;", new Character(9827));@b@    escapeStrings.put("&hearts;", new Character(9829));@b@    escapeStrings.put("&diams;", new Character(9830));@b@    escapeStrings.put("&quot;", new Character('"'));@b@    escapeStrings.put("&amp;", new Character('&'));@b@    escapeStrings.put("&lt;", new Character('<'));@b@    escapeStrings.put("&gt;", new Character('>'));@b@    escapeStrings.put("&OElig;", new Character(338));@b@    escapeStrings.put("&oelig;", new Character(339));@b@    escapeStrings.put("&Scaron;", new Character(352));@b@    escapeStrings.put("&scaron;", new Character(353));@b@    escapeStrings.put("&Yuml;", new Character(376));@b@    escapeStrings.put("&circ;", new Character(710));@b@    escapeStrings.put("&tilde;", new Character(732));@b@    escapeStrings.put("&ensp;", new Character(8194));@b@    escapeStrings.put("&emsp;", new Character(8195));@b@    escapeStrings.put("&thinsp;", new Character(8201));@b@    escapeStrings.put("&zwnj;", new Character(8204));@b@    escapeStrings.put("&zwj;", new Character(8205));@b@    escapeStrings.put("&lrm;", new Character(8206));@b@    escapeStrings.put("&rlm;", new Character(8207));@b@    escapeStrings.put("&ndash;", new Character(8211));@b@    escapeStrings.put("&mdash;", new Character(8212));@b@    escapeStrings.put("&lsquo;", new Character(8216));@b@    escapeStrings.put("&rsquo;", new Character(8217));@b@    escapeStrings.put("&sbquo;", new Character(8218));@b@    escapeStrings.put("&ldquo;", new Character(8220));@b@    escapeStrings.put("&rdquo;", new Character(8221));@b@    escapeStrings.put("&bdquo;", new Character(8222));@b@    escapeStrings.put("&dagger;", new Character(8224));@b@    escapeStrings.put("&Dagger;", new Character(8225));@b@    escapeStrings.put("&permil;", new Character(8240));@b@    escapeStrings.put("&lsaquo;", new Character(8249));@b@    escapeStrings.put("&rsaquo;", new Character(8250));@b@    escapeStrings.put("&euro;", new Character(8364));@b@@b@    UNSAFE_TAGS = new String[] { "script", "style", "object", "applet", "!--" };@b@@b@    Set set = new HashSet();@b@    set.add(Character.UnicodeBlock.HANGUL_JAMO);@b@    set.add(Character.UnicodeBlock.CJK_RADICALS_SUPPLEMENT);@b@    set.add(Character.UnicodeBlock.KANGXI_RADICALS);@b@    set.add(Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION);@b@    set.add(Character.UnicodeBlock.HIRAGANA);@b@    set.add(Character.UnicodeBlock.KATAKANA);@b@    set.add(Character.UnicodeBlock.BOPOMOFO);@b@    set.add(Character.UnicodeBlock.HANGUL_COMPATIBILITY_JAMO);@b@    set.add(Character.UnicodeBlock.KANBUN);@b@    set.add(Character.UnicodeBlock.BOPOMOFO_EXTENDED);@b@    set.add(Character.UnicodeBlock.KATAKANA_PHONETIC_EXTENSIONS);@b@    set.add(Character.UnicodeBlock.ENCLOSED_CJK_LETTERS_AND_MONTHS);@b@    set.add(Character.UnicodeBlock.CJK_COMPATIBILITY);@b@    set.add(Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A);@b@    set.add(Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS);@b@    set.add(Character.UnicodeBlock.HANGUL_SYLLABLES);@b@    set.add(Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS);@b@    set.add(Character.UnicodeBlock.CJK_COMPATIBILITY_FORMS);@b@    set.add(Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS);@b@    set.add(Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B);@b@    set.add(Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT);@b@    CJK_BLOCKS = Collections.unmodifiableSet(set);@b@@b@    hexChars = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };@b@  }@b@}

2.HtmlToText类

package com.google.gdata.util.common.html;@b@@b@import com.google.gdata.util.common.base.StringUtil;@b@import java.util.regex.Matcher;@b@import java.util.regex.Pattern;@b@@b@public final class HtmlToText@b@{@b@  private static final Pattern htmlNewlinePattern = Pattern.compile("\\s*<(br|/?p)>\\s*");@b@  private static final Pattern htmlListPattern = Pattern.compile("\\s*<li>\\s*");@b@  private static final Pattern htmlTagPattern = Pattern.compile("</?([^<]*)>");@b@  public static final int EMAIL_LINE_WIDTH_MAX = 72;@b@@b@  public static String htmlToPlainText(String html)@b@  {@b@    if (html == null) {@b@      throw new NullPointerException("Html parameter may not be null.");@b@    }@b@@b@    String text = StringUtil.stripAndCollapse(html);@b@@b@    text = htmlNewlinePattern.matcher(text).replaceAll("\n");@b@    text = htmlListPattern.matcher(text).replaceAll("\n- ");@b@    text = htmlTagPattern.matcher(text).replaceAll("");@b@    text = StringUtil.unescapeHTML(text).trim();@b@@b@    return StringUtil.fixedWidth(text.split("\n"), 72);@b@  }@b@}