View Javadoc

    1   /*
    2    * @(#) $Id: EntityRefEncoder.java,v 1.1.2.1 2005/01/18 07:20:43 otsuka Exp $
    3    * $Revision: 1.1.2.1 $
    4    * Copyright (c) 2000 Shin Kinoshita All Rights Reserved.
    5    */
    6
    7   package com.ozacc.mail.fetch.impl.sk_jp.text;
    8
    9   import java.io.IOException;
    10  import java.io.Reader;
    11  import java.io.Writer;
    12
    13  /***
    14   * &lt;&gt;&amp;&quot;を&amp;lt;&amp;gt;&amp;amp;&amp;quot;に
    15   * 変換するTranslatorです。
    16   * リエントラントなので、通常はINSTANCE/CANONICAL_INSTANCEを用いればよいです。
    17   * またStringオブジェクトに対してはencode()メソッドが使用できます。
    18   * @version $Revision: 1.1.2.1 $ $Date: 2005/01/18 07:20:43 $
    19   * @author Shin
    20   */
    21  public class EntityRefEncoder implements Translator {
    22      public static final EntityRefEncoder CANONICAL_INSTANCE =
    23              new EntityRefEncoder(true);
    24      public static final EntityRefEncoder INSTANCE =
    25              new EntityRefEncoder(false);
    26
    27      public EntityRefEncoder() {
    28          this(false);
    29      }
    30      public EntityRefEncoder(boolean canonical) {
    31          setCanonical(canonical);
    32      }
    33
    34      private boolean canonicalStatus;
    35      private void setCanonical(boolean canonical) {
    36  //  public void setCanonical(boolean canonical) {
    37          this.canonicalStatus = canonical;
    38      }
    39
    40      /***
    41       * 文字ストリームから入力した文字列を任意の変換を
    42       * 行いながら出力ストリームに書き出します。
    43       * <p>
    44       * </p>
    45       */
    46      public void translate(Reader r, Writer w) throws IOException {
    47          int c;
    48          while ((c = r.read()) != -1) {
    49              translate((char)c, w, canonicalStatus);
    50          }
    51          w.flush();
    52      }
    53
    54      public String translate(String source) {
    55          return encode(source);
    56      }
    57  /*
    58      public static String encode(String s) {
    59          if (s == null) return "";
    60
    61          StringWriter w = new StringWriter();
    62          try {
    63              EntityRefEncoder.INSTANCE.translate(new StringReader(s), w);
    64          } catch (IOException e) {
    65              throw new RuntimeException();
    66          }
    67          return w.toString();
    68      }
    69  */
    70
    71      /***
    72       * 文字列の実体参照化を行います。
    73       * @param s 対象文字列
    74       * @return 変換後文字列
    75       */
    76      // 似たようなコードを書きたくは無いが高速化の為…
    77      public static String encode(String s) {
    78          if (s == null) return "";
    79
    80          int len = s.length();
    81          StringBuffer buf = new StringBuffer(len + 128);
    82          char c;
    83
    84          for (int i = 0; i < len; i++) {
    85              c = s.charAt(i);
    86              switch (c) {
    87                  case '<': buf.append("&lt;"); break;
    88                  case '>': buf.append("&gt;"); break;
    89                  case '&': buf.append("&amp;"); break;
    90                  case '"': buf.append("&quot;"); break;
    91                  default:
    92                      buf.append(c);
    93              }
    94          }
    95          return new String(buf);
    96      }
    97
    98      /***
    99       * 特定の文字を実体参照に変換して書き出します。
    100      */
    101     public static void translate(char c, Writer w, boolean canonical)
    102                 throws IOException {
    103         switch (c) {
    104             case '<': w.write("&lt;"); break;
    105             case '>': w.write("&gt;"); break;
    106             case '&': w.write("&amp;"); break;
    107             case '"': w.write("&quot;"); break;
    108             case '\r':
    109             case '\n':
    110                 if (canonical) {
    111                     w.write("&#");
    112                     w.write(Integer.toString(c));
    113                     w.write(';');
    114                 } else {
    115                     w.write(c);
    116                 }
    117                 break;
    118             default:
    119                 w.write(c);
    120         }
    121     }
    122
    123     /***
    124      * 実体参照変換されている文字列をもとに戻します。
    125      * @param s 対象文字列
    126      * @return 変換後文字列
    127      */
    128     public static String decode(String s) {
    129         if (s == null) return "";
    130
    131         int len = s.length();
    132         StringBuffer buf = new StringBuffer(len);
    133         char c;
    134
    135         for (int i = 0; i < len; i++) {
    136             c = s.charAt(i);
    137             if (c != '&' || i > len - 4) {
    138                 buf.append(c);
    139                 continue;
    140             }
    141             if ((s.charAt(i + 2) == 't' || s.charAt(i + 2) == 'T') &&
    142                 s.charAt(i + 3) == ';') {
    143                 switch (s.charAt(i + 1)) {
    144                     case 'l':
    145                     case 'L':
    146                         buf.append('<');
    147                         i += 3;
    148                         continue;
    149                     case 'g':
    150                     case 'G':
    151                         buf.append('>');
    152                         i += 3;
    153                         continue;
    154                 }
    155             } else if (i < len - 4 &&
    156                 (s.charAt(i + 1) == 'a' || s.charAt(i + 1) == 'A') &&
    157                 (s.charAt(i + 2) == 'm' || s.charAt(i + 2) == 'M') &&
    158                 (s.charAt(i + 3) == 'p' || s.charAt(i + 3) == 'P') &&
    159                 s.charAt(i + 4) == ';') {
    160                 buf.append('&');
    161                 i += 4;
    162                 continue;
    163             } else if (i < len - 5 &&
    164                 (s.charAt(i + 1) == 'q' || s.charAt(i + 1) == 'Q') &&
    165                 (s.charAt(i + 2) == 'u' || s.charAt(i + 2) == 'U') &&
    166                 (s.charAt(i + 3) == 'o' || s.charAt(i + 3) == 'O') &&
    167                 (s.charAt(i + 4) == 't' || s.charAt(i + 4) == 'T') &&
    168                 s.charAt(i + 5) == ';') {
    169                 buf.append('"');
    170                 i += 5;
    171                 continue;
    172             }
    173             buf.append(c);
    174         }
    175         return new String(buf);
    176     }
    177 }