View Javadoc

    1   /*
    2    * @(#) $Id: UnicodeCorrector.java,v 1.1.2.1 2005/01/18 07:20:36 otsuka Exp $
    3    * $Revision: 1.1.2.1 $
    4    * Copyright (c) 2000 Shin Kinoshita All Rights Reserved.
    5    */
    6   package com.ozacc.mail.fetch.impl.sk_jp.io;
    7
    8   import java.io.UnsupportedEncodingException;
    9   import java.util.HashMap;
    10  import java.util.Map;
    11
    12  /***
    13   * UnicodeCorrector.
    14   * <p>
    15   * CorrectOutputStreamWriterで用いられる文字列バッファ補正クラスです。<br>
    16   * 出力エンコーディングによって補正すべき文字コードが異なるので、
    17   * 実際の補正処理はサブクラスで行います。<br>
    18   *
    19   * 対応しているのは以下のコンバータ名です。
    20   * </p>
    21   * <UL>
    22   * <LI>ISO2022JP
    23   * <LI>ISO-2022-JP
    24   * <LI>EUC-JP
    25   * <LI>EUCJIS
    26   * <LI>SJIS
    27   * <LI>Shift_JIS
    28   * <LI>MS932
    29   * <LI>Windows-31J
    30   * </UL>
    31   * @author Shin
    32   * @version $Revision: 1.1.2.1 $ $Date: 2005/01/18 07:20:36 $
    33   */
    34  public abstract class UnicodeCorrector {
    35      private static final Map correctorMap = new HashMap();
    36      static {
    37          // x-sjis-cp932等でおかしく変換されたUnicodeを他のエンコーディングで
    38          // 出力する場合です
    39          correctorMap.put("iso2022jp", FromCP932Corrector.class);
    40          correctorMap.put("iso-2022-jp", FromCP932Corrector.class);
    41          correctorMap.put("euc-jp", FromCP932Corrector.class);
    42          correctorMap.put("eucjis", FromCP932Corrector.class);
    43          // 同じ"SJIS"でもSunとMS-VMでは異なります。
    44          // Sun-JDK1.1はSJISはx-sjis-jdk-1.1.7で、MS-VMはx-sjis-cp932です。
    45          // しかし、MS-JDK中のクラスライブラリだけはx-sjis-jdk-1.1.7相当になるので
    46          // 困ったものです。(ファイル書き出し等のときのみおかしくなる)
    47          // これはWindowsネイティブな変換表で生成されたUnicodeを
    48          // x-sjis-jdk-1.1.7で出力するためのものです。
    49          correctorMap.put("sjis", FromCP932Corrector.class);
    50          correctorMap.put("shift_jis", FromCP932Corrector.class);
    51          // MS-VMでファイル出力を行う場合に限り、こちらでなければなりません。
    52          //      correctorMap.put("sjis", ToCP932Corrector.class);
    53          // JDK1.2からはWindowsのデフォルトが"MS932"(x-sjis-cp932相当)となりました。
    54          // これで、他のエンコーディングで変換された(正しい)Unicodeが"ms932"
    55          // での出力時におかしくなってしまいます。
    56          // これを補正します。
    57          correctorMap.put("ms932", ToCP932Corrector.class);
    58          correctorMap.put("windows-31j", ToCP932Corrector.class);
    59      }
    60
    61      /***
    62       * Create an UnicodeCorrector that uses
    63       * the named character encoding.
    64       * @param  enc  Name of the encoding to be used
    65       * @exception  UnsupportedEncodingException
    66       *             If the named encoding is not supported
    67       */
    68      public static UnicodeCorrector getInstance(String enc)
    69              throws UnsupportedEncodingException {
    70          Class correctorClass = (Class)correctorMap.get(enc.toLowerCase());
    71          if (correctorClass == null) {
    72              throw new UnsupportedEncodingException(enc);
    73          }
    74          try {
    75              return (UnicodeCorrector)correctorClass.newInstance();
    76          } catch (Exception e) {
    77              throw new UnsupportedEncodingException(
    78                      correctorClass + " cannot get newInstance.\n" + e);
    79          }
    80      }
    81
    82      /***
    83       * Unicode文字配列の補正を行います。
    84       * <p>
    85       * 特定の文字を特定エンコーディングで出力しようとした際の
    86       * sun.ioコンバータでは正常に変換できない部分を補正します。
    87       * </p>
    88       * @param  cbuf  Buffer of characters
    89       * @param  off   Offset from which to start writing characters
    90       * @param  len   Number of characters to write
    91       * @return Result that corrected.
    92       *         Note:Return array is different from <code>cbuf</code>
    93       *              in case of different result size.
    94       */
    95      public char[] correct(char cbuf[], int off, int len) {
    96          StringBuffer buf = new StringBuffer();
    97          for (int i = off; i < len; i++) {
    98              buf.append(correct(cbuf[i]));
    99          }
    100         return new String(buf).toCharArray();
    101     }
    102
    103     public String correct(String s) {
    104         StringBuffer buf = new StringBuffer();
    105         for (int i = 0; i < s.length(); i++) {
    106             buf.append(correct(s.charAt(i)));
    107         }
    108         return new String(buf);
    109     }
    110
    111     // 性能的にこれをabstractにするのはためらったが・・・
    112     public abstract char correct(char c);
    113
    114     /***
    115      * 新しいUnicodeCorrectorを追加します。
    116      * <p>
    117      * このソースコードを変えずに、動的に新たな出力エンコーディングに
    118      * 対応したUnicodeCorrectorを登録したい場合に用います。
    119      * </p>
    120      * @param enc 対応するエンコーディング名
    121      * @param correctorClass UnicodeCorrectorサブクラスのClassオブジェクト
    122      */
    123     public static void addCorrector(String enc, Class correctorClass) {
    124         if (!correctorClass.isInstance(UnicodeCorrector.class)) {
    125             throw new IllegalArgumentException(
    126                     "Corrector is not UnicodeCorrector type.");
    127         }
    128         correctorMap.put(enc, correctorClass);
    129     }
    130 }