001    /*
002     * Copyright (c) 2009 The openGion Project.
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     *     http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
013     * either express or implied. See the License for the specific language
014     * governing permissions and limitations under the License.
015     */
016    package org.opengion.fukurou.mail;
017    
018    // import java.io.InputStream;
019    // import java.io.OutputStream;
020    // import java.io.ByteArrayOutputStream;
021    // import java.io.ByteArrayInputStream;
022    import java.io.UnsupportedEncodingException;
023    // import java.io.IOException;
024    
025    // import javax.activation.DataHandler;
026    // import javax.activation.DataSource;
027    import javax.mail.internet.InternetAddress;
028    import javax.mail.internet.MimeMessage;
029    // import javax.mail.internet.MimeUtility;
030    import javax.mail.MessagingException;
031    // import com.sun.mail.util.BASE64EncoderStream;
032    
033    // import java.nio.charset.Charset;             // 5.5.2.6 (2012/05/25)
034    
035    /**
036     * MailCharset は、E-Mail 送信時ã?エンコードに応じたå?ç�?‚’行う為のã€?
037     * インターフェースですã?
038     *
039     * E-Mail で日本語を送信する場合ã?ISO-2022-JP(JISコーãƒ?化してã€?bit で
040     * エンコードして送信するå¿?¦�がありますが、Windows系の特殊文字や、unicodeと
041     * æ–?­—ã?マッピングが異なる文字などがã?æ–?­—化けしますã?
042     * 対応方法としてはã€?
043     * 『1.Windows-31J + 8bit 送信ã€?
044     * 『2.ISO-2022-JP に独自変換 + 7bit 送信ã€?
045     * の方法がありますã?
046     * 今回、この?’つの方法につã�?�¦、それぞれサブクラス化を行い、å?ç�?�§きるように
047     * したのがã?こã?インターフェース、およã?、サブクラスですã?
048     *
049     * 『1.Windows-31J + 8bit 送信』ã?方法ã?ã€??常の JavaMail API に準拠して
050     * 処ç�?‚’行う、Mail_Windows31J_Charset サブクラスで実è£?�—てã�?�¾すã?
051     * 古ã�?ƒ¡イラーおよび、古ã�?ƒ¡ールサーバã?ではメール転送できなã�?‚ºã€?
052     * こã?方式ã?、社å†?�§使用する場合ã?みに、利用できますが、主としてWindows系の
053     * 社å†?‚·スãƒ?ƒ においては、こちらã?方がã?なにかとトラブルは少なã�?�¨思いますã?
054     *
055     * 『2.ISO-2022-JP に独自変換 + 7bit 送信』ã?実è£??ã€?
056     * JAVA PRESS Vol.37 (http://www.gihyo.co.jp/magazines/javapress)の
057     * 【特é›?ã€?決定版??サーバサイドJavaの日本語å?ç�?
058     *  第3ç«?¼šJavaMailの日本語å?ç�??ログラミング……木下信
059     *“ã?ルチã?ラãƒ?ƒˆフォーãƒ??な日本語メール送信è¡?完å?解説
060     * でのサンプルアプリケーション
061     * http://www.gihyo.co.jp/book/2004/225371/download/toku1_3.zip
062     * をã?使用して、Mail_ISO2022JP_Charset サブクラスで実è£?�—てã�?�¾すã?
063     *
064     * これらã?サブクラスは、MailCharsetFactory ファクトリクラスより、作æ?されますã?
065     * そã?場合ã?引数のキャラクタセãƒ?ƒˆ名ã?、Windows-31J 、MS932 かã?それ以外となってã�?�¾すã?
066     * それ以外がæŒ?®šされた場合ã?、ISO-2022-JP を使用しますã?
067     *
068     * @version  4.0
069     * @author   Kazuhiko Hasegawa
070     * @since    JDK5.0,
071     */
072    public interface MailCharset {
073    
074            /**
075             * ãƒ?‚­ストをセãƒ?ƒˆしますã?
076             * Part#setText() の代わりにこちらを使ã�?‚ˆã�?�«しますã?
077             *
078             * ※ å†?ƒ¨で、MessagingException が発生したå?合ã?、RuntimeException に変換されて throw されますã?
079             *
080             * @param mimeMsg MimeMessageæœ?¤§取り込み件数
081             * @param text    設定するテキスãƒ?
082             */
083            void setTextContent( MimeMessage mimeMsg, String text ) ;
084    
085            /**
086             * 日本語を含ã‚??ãƒ?ƒ€用ãƒ?‚­ストを生æ?しますã?
087             * 変換結果は ASCII なので、これをそã?まま setSubject ã‚?InternetAddress
088             * のパラメタとして使用してくださいã€?
089             *
090             * ※ å†?ƒ¨で、UnsupportedEncodingException が発生したå?合ã?、RuntimeException に変換されて throw されますã?
091             *
092             * @param text    設定するテキスãƒ?
093             *
094             * @return      日本語を含ã‚??ãƒ?ƒ€用ãƒ?‚­スãƒ?
095             */
096            String encodeWord( String text ) ;
097    
098            /**
099             * 日本語を含ã‚?‚¢ドレスを生成しますã?
100             * personal に、日本語が含まれると想定してã�?�¾すã?
101             * サブクラスで、日本語å?ç�?‚’行う場合ã?方法ã?、それぞれ異なりますã?
102             *
103             * ※ å†?ƒ¨で、UnsupportedEncodingException が発生したå?合ã?、RuntimeException に変換されて throw されますã?
104             *
105             * @param address    アドレス部åˆ?
106             * @param personal   日本語ã?説明部åˆ?
107             *
108             * @return      日本語を含ã‚?‚¢ドレス
109             */
110            InternetAddress getAddress( String address,String personal ) ;
111    
112            /**
113             * Content-Transfer-Encoding を指定するå?合ã? ビット数を返しますã?
114             *
115             * Windows系はã€?bit / ISO-2022-JP 系はã€?bit になりますã?
116             *
117             * @return      ビット数
118             */
119            String getBit() ;
120    }
121    
122    /**
123     * MailCharsetFactory は、MailCharset インターフェースを実è£?�—たサブクラスã‚?
124     * 作æ?する ファクトリクラスですã?
125     *
126     * 引数のキャラクタセãƒ?ƒˆ名が、Windows-31J 、MS932 の場合ã?ã€?
127     * 『1.Windows-31J + 8bit 送信ã€?の実è£?�§ある、Mail_Windows31J_Charset
128     * サブクラスを返しますã?
129     * それ以外がæŒ?®šされた場合ã?、ISO-2022-JP を使用して、ã??’.ISO-2022-JP に独自変換 + 7bit 送信ã€?
130     * の実è£?�§ある、Mail_ISO2022JP_Charset サブクラスを返しますã?
131     *
132     * @version  4.0
133     * @author   Kazuhiko Hasegawa
134     * @since    JDK5.0,
135     */
136    //class MailCharsetFactory {
137    //
138    //      /**
139    //       * インスタンスの生æ?を抑止しますã?
140    //       */
141    //      private MailCharsetFactory() {
142    //              // 何もありませんã€?PMD エラー回避)
143    //      }
144    //
145    //      /**
146    //       * キャラクタセãƒ?ƒˆに応じたã?MailCharset オブジェクトを返しますã?
147    //       *
148    //       * Windows-31J 、MS932 、Shift_JIS の場合ã?、Mail_Windows31J_Charset
149    //       * そã?他ã?、ISO-2022-JP として、Mail_ISO2022JP_Charset を返しますã?
150    //       *
151    //       * 注意:null の場合ã?、デフォルトではなくã?Mail_ISO2022JP_Charset を返しますã?
152    //       *
153    //       * @param  charset キャラクタセãƒ?ƒˆ[Windows-31J/MS932/Shift_JIS/そã?他]
154    //       *
155    //       * @return MailCharset
156    //       */
157    //      static MailCharset newInstance( final String charset ) {
158    //              final MailCharset mcset;
159    //
160    //              if( "MS932".equalsIgnoreCase( charset ) ||
161    //                      "Shift_JIS".equalsIgnoreCase( charset ) ||
162    //                      "Windows-31J".equalsIgnoreCase( charset ) ) {
163    //                              mcset = new Mail_Windows31J_Charset( charset );
164    //              }
165    //              else {
166    //                      mcset = new Mail_ISO2022JP_Charset();
167    //              }
168    //              return mcset ;
169    //      }
170    //}
171    
172    /**
173     * MailCharset インターフェースを実è£?�—ã�?Windwos-31J エンコード時のサブクラスですã?
174     *
175     * 『1.Windows-31J + 8bit 送信ã€?の実è£?�§すã?
176     *
177     * @version  4.0
178     * @author   Kazuhiko Hasegawa
179     * @since    JDK5.0,
180     */
181    //class Mail_Windows31J_Charset implements MailCharset {
182    //      private final String charset ;                  // "Windows-31J" or "MS932"
183    //
184    //      /**
185    //       * 引数に、エンコード方式をæŒ?®šして、作æ?するコンストラクタですã?
186    //       *
187    //       * @param charset String
188    //       */
189    //      public Mail_Windows31J_Charset( final String charset ) {
190    //              this.charset = charset;
191    //      }
192    //
193    //      /**
194    //       * ãƒ?‚­ストをセãƒ?ƒˆしますã?
195    //       * Part#setText() の代わりにこちらを使ã�?‚ˆã�?�«しますã?
196    //       *
197    //       * @param mimeMsg MimeMessage
198    //       * @param text    String
199    //       * @throws RuntimeException(MessagingException)
200    //       */
201    //      public void setTextContent( final MimeMessage mimeMsg, final String text ) {
202    //              try {
203    //                      mimeMsg.setText( text,charset );                // "text/plain" Content
204    //              }
205    //              catch( MessagingException ex ) {
206    //                      String errMsg = "æŒ?®šã?ãƒ?‚­ストをセãƒ?ƒˆできませんã€?
207    //                                                              + "text=" + text + " , charset=" + charset ;
208    //                      throw new RuntimeException( errMsg,ex );
209    //              }
210    //      }
211    //
212    //      /**
213    //       * 日本語を含ã‚??ãƒ?ƒ€用ãƒ?‚­ストを生æ?しますã?
214    //       * 変換結果は ASCII なので、これをそã?まま setSubject ã‚?InternetAddress
215    //       * のパラメタとして使用してくださいã€?
216    //       *
217    //       * @param text    String
218    //       *
219    //       * @return      日本語を含ã‚??ãƒ?ƒ€用ãƒ?‚­スãƒ?
220    //       * @throws RuntimeException(UnsupportedEncodingException)
221    //       */
222    //      public String encodeWord( final String text ) {
223    //              try {
224    //                      return MimeUtility.encodeText( text, charset, "B" );
225    //              }
226    //              catch( UnsupportedEncodingException ex ) {
227    //                      String errMsg = "æŒ?®šã?エンコードが出来ませんã€?
228    //                                                              + "text=" + text + " , charset=" + charset ;
229    //                      throw new RuntimeException( errMsg,ex );
230    //              }
231    //      }
232    //
233    //      /**
234    //       * 日本語を含ã‚?‚¢ドレスを生成しますã?
235    //       * personal に、日本語が含まれると想定してã�?�¾すã?
236    //       * サブクラスで、日本語å?ç�?‚’行う場合ã?方法ã?、それぞれ異なりますã?
237    //       *
238    //       * @param address    String
239    //       * @param personal   String
240    //       *
241    //       * @return InternetAddress
242    //       * @throws RuntimeException(UnsupportedEncodingException)
243    //       */
244    //      public InternetAddress getAddress( final String address,final String personal ) {
245    //              try {
246    //                      return new InternetAddress( address,personal,charset );
247    //              }
248    //              catch( UnsupportedEncodingException ex ) {
249    //                      String errMsg = "æŒ?®šã?エンコードが出来ませんã€?
250    //                                                              + "address=" + address + " , charset=" + charset ;
251    //                      throw new RuntimeException( errMsg,ex );
252    //              }
253    //      }
254    //
255    //      /**
256    //       * Content-Transfer-Encoding を指定するå?合ã? ビット数を返しますã?
257    //       *
258    //       * Windows系はã€?bit / ISO-2022-JP 系はã€?bit になりますã?
259    //       *
260    //       * @return      ビット数("8bit" 固å®?
261    //       */
262    //      public String getBit() {
263    //              return "8bit" ;
264    //      }
265    //}
266    
267    /**
268     * MailCharset インターフェースを実è£?�—ã�?ISO-2022-JP エンコード時のサブクラスですã?
269     *
270     * 『2.ISO-2022-JP に独自変換 + 7bit 送信ã€?の実è£?�§すã?
271     *
272     * @version  4.0
273     * @author   Kazuhiko Hasegawa
274     * @since    JDK5.0,
275     */
276    //class Mail_ISO2022JP_Charset implements MailCharset {
277    //
278    //      /**
279    //       * プラãƒ?ƒˆフォーãƒ?¾�存ã?ãƒ?ƒ•ォルトã? Charset ですã?
280    //       * プラãƒ?ƒˆフォーãƒ?¾�存æ?をè?慮する場合ã?エンコード指定で作æ?しておく事をお勧めしますã?
281    //       *
282    //       * @og.rev 5.5.2.6 (2012/05/25) findbugs対å¿?
283    //       */
284    //      private static final Charset DEFAULT_CHARSET = Charset.defaultCharset() ;
285    //
286    //      /**
287    //       * ãƒ?‚­ストをセãƒ?ƒˆしますã?
288    //       * Part#setText() の代わりにこちらを使ã�?‚ˆã�?�«しますã?
289    //       *
290    //       * @param mimeMsg MimeMessage
291    //       * @param text    String
292    //       * @throws RuntimeException(MessagingException)
293    //       */
294    //      public void setTextContent( final MimeMessage mimeMsg, final String text ) {
295    //              try {
296    //                      // mimeMsg.setText(text, "ISO-2022-JP");
297    //                      mimeMsg.setDataHandler(new DataHandler(new JISDataSource(text)));
298    //              }
299    //              catch( MessagingException ex ) {
300    //                      String errMsg = "æŒ?®šã?ãƒ?‚­ストをセãƒ?ƒˆできませんã€?
301    //                                                              + "text=" + text ;
302    //                      throw new RuntimeException( errMsg,ex );
303    //              }
304    //      }
305    //
306    //      /**
307    //       * 日本語を含ã‚??ãƒ?ƒ€用ãƒ?‚­ストを生æ?しますã?
308    //       * 変換結果は ASCII なので、これをそã?まま setSubject ã‚?InternetAddress
309    //       * のパラメタとして使用してくださいã€?
310    //       *
311    //       * @param text    String
312    //       *
313    //       * @return      日本語を含ã‚??ãƒ?ƒ€用ãƒ?‚­スãƒ?
314    //       * @throws RuntimeException(UnsupportedEncodingException)
315    //       */
316    //      public String encodeWord( final String text ) {
317    //              try {
318    //                      return "=?ISO-2022-JP?B?" +
319    //                              new String(
320    //                                      BASE64EncoderStream.encode(
321    //                                              CharCodeConverter.sjisToJis(
322    //                                                      UnicodeCorrecter.correctToCP932(text).getBytes("Windows-31J")
323    //                                              )
324    //                                      )
325    //                              ,DEFAULT_CHARSET ) + "?=";              // 5.5.2.6 (2012/05/25) findbugs対å¿?
326    //              }
327    //              catch( UnsupportedEncodingException ex ) {
328    //                      String errMsg = "æŒ?®šã?エンコードが出来ませんã€?
329    //                                                              + "text=" + text + " , charset=Windows-31J" ;
330    //                      throw new RuntimeException( errMsg,ex );
331    //              }
332    //      }
333    //
334    //      /**
335    //       * 日本語を含ã‚?‚¢ドレスを生成しますã?
336    //       * personal に、日本語が含まれると想定してã�?�¾すã?
337    //       * サブクラスで、日本語å?ç�?‚’行う場合ã?方法ã?、それぞれ異なりますã?
338    //       *
339    //       * @param address    String
340    //       * @param personal   String
341    //       *
342    //       * @return InternetAddress
343    //       * @throws RuntimeException(UnsupportedEncodingException)
344    //       */
345    //      public InternetAddress getAddress( final String address,final String personal ) {
346    //              try {
347    //                      return new InternetAddress( address,encodeWord( personal ) );
348    //              }
349    //              catch( UnsupportedEncodingException ex ) {
350    //                      String errMsg = "æŒ?®šã?エンコードが出来ませんã€?
351    //                                                              + "address=" + address ;
352    //                      throw new RuntimeException( errMsg,ex );
353    //              }
354    //      }
355    //
356    //      /**
357    //       * Content-Transfer-Encoding を指定するå?合ã? ビット数を返しますã?
358    //       *
359    //       * Windows系はã€?bit / ISO-2022-JP 系はã€?bit になりますã?
360    //       *
361    //       * @return      ビット数("7bit" 固å®?
362    //       */
363    //      public String getBit() {
364    //              return "7bit" ;
365    //      }
366    //}
367    
368    /**
369     * ãƒ?‚­ストã?本æ–?‚’送信するための DataSource ですã?
370     *
371     * Windows-31J でバイトコードに変換した後ã?独自エンコードにてã€?
372     * Shift-JIS â‡?JIS 変換してã�?�¾すã?
373     *
374     * @version  4.0
375     * @author   Kazuhiko Hasegawa
376     * @since    JDK5.0,
377     */
378    //class JISDataSource implements DataSource {
379    //      private final byte[] data;
380    //
381    //      public JISDataSource( final String str ) {
382    //              try {
383    //                      data = CharCodeConverter.sjisToJis(
384    //                              UnicodeCorrecter.correctToCP932(str).getBytes("Windows-31J"));
385    //
386    //              } catch (UnsupportedEncodingException e) {
387    //                      String errMsg = "Windows-31J でのエンコーãƒ?‚£ングがå?来ませんã€? + str;
388    //                      throw new RuntimeException( errMsg,e );
389    //              }
390    //      }
391    //
392    //      /**
393    //       * ãƒ??タの MIME タイプをæ–?­—å?の形で返しますã?
394    //       * かならず有効なタイプを返すべきですã?
395    //       * DataSource の実è£?�Œãƒ??タタイプを 決定できなã�??合ã?ã€?
396    //       * getContentType は "application/octet-stream" を返すことã‚?提案しますã?
397    //       *
398    //       * @return      MIME タイãƒ?
399    //       */
400    //      public String getContentType() {
401    //              return "text/plain; charset=ISO-2022-JP";
402    //      }
403    //
404    //      /**
405    //       * ãƒ??タを表ã�?InputStream を返しますã?
406    //       * それができなã�??合ã?適åˆ?�ª例外をスローしますã?
407    //       *
408    //       * @return InputStream
409    //       * @throws IOException
410    //       */
411    //      public InputStream getInputStream() throws IOException {
412    //              return new ByteArrayInputStream( data );
413    //      }
414    //
415    //      /**
416    //       * ãƒ??タが書込可能なã‚?OutputStream を返しますã?
417    //       * それができなã�??合ã?適åˆ?�ª例外をスローしますã?
418    //       *
419    //       * ※ こã?クラスでは実è£?�•れてã�?�¾せんã€?
420    //       *
421    //       * @return OutputStream
422    //       * @throws IOException
423    //       */
424    //      public OutputStream getOutputStream() throws IOException {
425    //              String errMsg = "こã?クラスでは実è£?�•れてã�?�¾せんã€?;
426    //      //      throw new UnsupportedOperationException( errMsg );
427    //              throw new IOException( errMsg );
428    //      }
429    //
430    //      /**
431    //       * こã?オブジェクトã? '名前' を返しますã?
432    //       * こã?名前は下層のオブジェクトã?性質によりますã?
433    //       * ファイルをカプセル化すã‚?DataSource なã‚?オブジェクトã?
434    //       * ファイル名を返すようにするかもしれませんã€?
435    //       *
436    //       * @return      オブジェクトã?名前
437    //       */
438    //      public String getName() {
439    //              return "JISDataSource";
440    //      }
441    //}
442    
443    /**
444     * æ–?­—関係ã?コンバã?タですã?
445     * ä¸?ƒ¨コードã?オリジナルは<a href="http://www-cms.phys.s.u-tokyo.ac.jp/~naoki/CIPINTRO/CCGI/kanjicod.html">Japanese Kanji Code</a>にて公開されてã�?‚‹もã?ですã?
446     * またã?http://www.sk-jp.com/cgi-bin/treebbs.cgi?kako=1&all=644&s=681
447     * にて YOSI さんがå?開されたコードも参è?にしてã�?�¾ã�?とã�?�†か実質同じでã�?ã€?
448     *
449     * @version  4.0
450     * @author   Kazuhiko Hasegawa
451     * @since    JDK5.0,
452     */
453    //class CharCodeConverter {
454    //      private static final byte[] SJIS_KANA;  // 5.1.9.0 (2010/09/01) public â‡?private へ変更
455    //
456    //      /**
457    //       * インスタンスの生æ?を抑止しますã?
458    //       */
459    //      private CharCodeConverter() {
460    //              // 何もありませんã€?PMD エラー回避)
461    //      }
462    //
463    //      static {
464    //              try {
465    //                      // 全角への変換ãƒ??ブル
466    //                      SJIS_KANA = "。ã?」ã?・ヲァィゥェォャュョãƒ??アイウエオカキクケコサシスセソタチツãƒ?ƒˆナニヌネノハヒフヘã?マミãƒ?ƒ¡モヤユヨラリルレロワン゛ã?".getBytes("Shift_JIS");
467    //              } catch( UnsupportedEncodingException ex ) {
468    //                      throw new RuntimeException( "CANT HAPPEN",ex );
469    //              }
470    //      }
471    //
472    //      /**
473    //       * Shift_JIS エンコーãƒ?‚£ングスキーãƒ?�«基づくバイトå?ã‚?
474    //       * ISO-2022-JP エンコーãƒ?‚£ングスキーãƒ?�«変換しますã?
475    //       * 「半角カナã?は対応するå?角文字に変換しますã?
476    //       *
477    //       * @param sjisBytes byte[] エンコードするShift_JISバイトé?åˆ?
478    //       *
479    //       * @return byte[] 変換後ã?ISO-2022-JP(JIS)バイトé?åˆ?not null)
480    //       */
481    //      public static byte[] sjisToJis( final byte[] sjisBytes ) {
482    //              ByteArrayOutputStream out = new ByteArrayOutputStream();
483    //              boolean nonAscii = false;
484    //              int len = sjisBytes.length;
485    //              for(int i = 0; i < len; i++ ) {
486    //                      if(sjisBytes[i] >= 0) {
487    //                              if(nonAscii) {
488    //                                      nonAscii = false;
489    //                                      out.write(0x1b);
490    //                                      out.write('(');
491    //                                      out.write('B');
492    //                              }
493    //                              out.write(sjisBytes[i]);
494    //                      } else {
495    //                              if(!nonAscii) {
496    //                                      nonAscii = true;
497    //                                      out.write(0x1b);
498    //                                      out.write('$');
499    //                                      out.write('B');
500    //                              }
501    //                              int bt = sjisBytes[i] & 0xff;
502    //                              if(bt >= 0xa1 && bt <= 0xdf) {
503    //                                      // 半角カナã?全角に変換
504    //                                      int kanaIndex = (bt - 0xA1) * 2;
505    //                                      sjisToJis(out, SJIS_KANA[kanaIndex], SJIS_KANA[kanaIndex + 1]);
506    //                              } else {
507    //                                      i++;
508    //                                      if(i == len) { break; }
509    //                                      sjisToJis(out, sjisBytes[i - 1], sjisBytes[i]);
510    //                              }
511    //                      }
512    //              }
513    //              if(nonAscii) {
514    //                      out.write(0x1b);
515    //                      out.write('(');
516    //                      out.write('B');
517    //              }
518    //              return out.toByteArray();
519    //      }
520    //
521    //      /**
522    //       * ?‘文字ã??’バイãƒ?Shift_JIS コードを JIS コードに変換して書きå?しますã?
523    //       */
524    //      private static void sjisToJis(
525    //                              final ByteArrayOutputStream out, final byte bhi, final byte blo) {
526    //              int hi = (bhi << 1) & 0xFF;
527    //              int lo = blo & 0xFF;
528    //              if(lo < 0x9F) {
529    //                      if(hi < 0x3F) { hi += 0x1F; } else { hi -= 0x61; }
530    //                      if(lo > 0x7E) { lo -= 0x20; } else { lo -= 0x1F; }
531    //              } else {
532    //                      if(hi < 0x3F) { hi += 0x20; } else { hi -= 0x60; }
533    //                      lo -= 0x7E;
534    //              }
535    //              out.write(hi);
536    //              out.write(lo);
537    //      }
538    //}
539    
540    /**
541     * unicode と、JIS とのæ–?­—コードã?関係で、変換してã�?�¾すã?
542     *
543     * 0x301c(&#x301c;) をã?0xff5e(&#xff5e;) へã€?
544     * 0x2016(&#x2016;) をã?0x2225(&#x2225;) へã€?
545     * 0x2212(&#x2212;) をã?0xff0d(&#xff0d;) へã€?
546     * それぞれコード変換しますã?
547     *
548     * @version  4.0
549     * @author   Kazuhiko Hasegawa
550     * @since    JDK5.0,
551     */
552    //class UnicodeCorrecter {
553    //
554    //      /**
555    //       * インスタンスの生æ?を抑止しますã?
556    //       */
557    //      private UnicodeCorrecter() {
558    //              // 何もありませんã€?PMD エラー回避)
559    //      }
560    //
561    //      /**
562    //       * Unicode æ–?­—å?の補正を行いますã?
563    //       * "MS932" コンバã?タでエンコードしようとした際に
564    //       * 正常に変換できなã�?ƒ¨åˆ?‚’補正しますã?
565    //       */
566    //      public static String correctToCP932( final String str ) {
567    //              String rtn = "";
568    //
569    //              if( str != null ) {
570    //                      int cnt = str.length();
571    //                      StringBuilder buf = new StringBuilder( cnt );
572    //                      for(int i=0; i<cnt; i++) {
573    //                              buf.append(correctToCP932(str.charAt(i)));
574    //                      }
575    //                      rtn = buf.toString() ;
576    //              }
577    //              return rtn ;
578    //      }
579    //
580    //      /**
581    //       * キャラクタ単位に、Unicode æ–?­—å?の補正を行いますã?
582    //       *
583    //       * 風間殿のペã?ジを参è€?�«してã�?�¾すã?
584    //       * @see <a href="http://www.ingrid.org/java/i18n/encoding/ja-conv.html" target="_blank">
585    //       * http://www.ingrid.org/java/i18n/encoding/ja-conv.html</a>
586    //       */
587    //      public static char correctToCP932( final char ch ) {
588    //              char rtn = ch;
589    //
590    //              switch (ch) {
591    //      //              case 0x00a2:    return 0xffe0;          // ≪
592    //      //              case 0x00a3:    return 0xffe1;          // ?£
593    //      //              case 0x00ac:    return 0xffe2;          // μ
594    //      //              case 0x03bc:    return 0x00b5;          // ・
595    //      //              case 0x2014:    return 0x2015;          // ??
596    //      //              case 0x2016:    return 0x2225;          // ≫
597    //      //              case 0x2212:    return 0xff0d;          // �
598    //      //              case 0x226a:    return 0x00ab;          // ∥
599    //      //              case 0x226b:    return 0x00bb;          // ヴ
600    //      //              case 0x301c:    return 0xff5e;          // ??
601    //      //              case 0x30f4:    return 0x3094;          // ??
602    //      //              case 0x30fb:    return 0x00b7;          // ??
603    //      //              case 0xff0c:    return 0x00b8;          // ?¡
604    //      //              case 0xffe3:    return 0x00af;          // ?¢
605    //
606    //                      case 0x00a2:    rtn = 0xffe0; break;            // ??(1-81, CENT SIGN)
607    //                      case 0x00a3:    rtn = 0xffe1; break;            // ?¡ (1-82, POUND SIGN)
608    //                      case 0x00a5:    rtn = 0x005c; break;            // \ (D/12, YEN SIGN)
609    //                      case 0x00ac:    rtn = 0xffe2; break;            // ?¢ (2-44, NOT SIGN)
610    //                      case 0x2016:    rtn = 0x2225; break;            // ∥ (1-34, DOUBLE VERTICAL LINE)
611    //                      case 0x203e:    rtn = 0x007e; break;            // ~ (F/14, OVERLINE)
612    //                      case 0x2212:    rtn = 0xff0d; break;            // ??(1-61, MINUS SIGN)
613    //                      case 0x301c:    rtn = 0xff5e; break;            // ??(1-33, WAVE DASH)
614    //
615    //      //              case 0x301c:    return 0xff5e;
616    //      //              case 0x2016:    return 0x2225;
617    //      //              case 0x2212:    return 0xff0d;
618    //                      default:                break;                  // 4.0.0 (2005/01/31)
619    //              }
620    //              return rtn;
621    //      }
622    //}