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 * MailCharsetFactory は、MailCharset インターフェースを実?たサブクラス? 037 * 作?する ファクトリクラスです? 038 * 039 * 引数のキャラクタセ?名が、Windows-31J 、MS932 の場合?? 040 * 『1.Windows-31J + 8bit 送信?の実?ある、Mail_Windows31J_Charset 041 * サブクラスを返します? 042 * それ以外が?された場合?、ISO-2022-JP を使用して、??.ISO-2022-JP に独自変換 + 7bit 送信? 043 * の実?ある、Mail_ISO2022JP_Charset サブクラスを返します? 044 * 045 * @version 4.0 046 * @author Kazuhiko Hasegawa 047 * @since JDK5.0, 048 */ 049 class MailCharsetFactory { 050 051 /** 052 * インスタンスの生?を抑止します? 053 */ 054 private MailCharsetFactory() { 055 // 何もありません?PMD エラー回避) 056 } 057 058 /** 059 * キャラクタセ?に応じた?MailCharset オブジェクトを返します? 060 * 061 * Windows-31J 、MS932 、Shift_JIS の場合?、Mail_Windows31J_Charset 062 * そ?他?、ISO-2022-JP として、Mail_ISO2022JP_Charset を返します? 063 * 064 * 注意:null の場合?、デフォルトではなく?Mail_ISO2022JP_Charset を返します? 065 * 066 * @param charset キャラクタセ?[Windows-31J/MS932/Shift_JIS/そ?他] 067 * 068 * @return MailCharset 069 */ 070 static MailCharset newInstance( final String charset ) { 071 final MailCharset mcset; 072 073 if( "MS932".equalsIgnoreCase( charset ) || 074 "Shift_JIS".equalsIgnoreCase( charset ) || 075 "Windows-31J".equalsIgnoreCase( charset ) ) { 076 mcset = new Mail_Windows31J_Charset( charset ); 077 } 078 else { 079 mcset = new Mail_ISO2022JP_Charset(); 080 } 081 return mcset ; 082 } 083 084 /** 085 * MailCharset インターフェースを実??Windwos-31J エンコード時のサブクラスです? 086 * 087 * 『1.Windows-31J + 8bit 送信?の実?す? 088 * 089 * @version 4.0 090 * @author Kazuhiko Hasegawa 091 * @since JDK5.0, 092 */ 093 static class Mail_Windows31J_Charset implements MailCharset { 094 private final String charset ; // "Windows-31J" or "MS932" 095 096 /** 097 * 引数に、エンコード方式を?して、作?するコンストラクタです? 098 * 099 * @param charset String 100 */ 101 public Mail_Windows31J_Charset( final String charset ) { 102 this.charset = charset; 103 } 104 105 /** 106 * ?ストをセ?します? 107 * Part#setText() の代わりにこちらを使??します? 108 * 109 * ※ ?で、MessagingException が発生した?合?、RuntimeException に変換されて throw されます? 110 * 111 * @param mimeMsg MimeMessage 112 * @param text String 113 */ 114 public void setTextContent( final MimeMessage mimeMsg, final String text ) { 115 try { 116 mimeMsg.setText( text,charset ); // "text/plain" Content 117 } 118 catch( MessagingException ex ) { 119 String errMsg = "???ストをセ?できません? 120 + "text=" + text + " , charset=" + charset ; 121 throw new RuntimeException( errMsg,ex ); 122 } 123 } 124 125 /** 126 * 日本語を含???用?ストを生?します? 127 * 変換結果は ASCII なので、これをそ?まま setSubject ?InternetAddress 128 * のパラメタとして使用してください? 129 * 130 * ※ ?で、UnsupportedEncodingException が発生した?合?、RuntimeException に変換されて throw されます? 131 * 132 * @param text String 133 * 134 * @return 日本語を含???用?ス? 135 */ 136 public String encodeWord( final String text ) { 137 try { 138 return MimeUtility.encodeText( text, charset, "B" ); 139 } 140 catch( UnsupportedEncodingException ex ) { 141 String errMsg = "??エンコードが出来ません? 142 + "text=" + text + " , charset=" + charset ; 143 throw new RuntimeException( errMsg,ex ); 144 } 145 } 146 147 /** 148 * 日本語を含?ドレスを生成します? 149 * personal に、日本語が含まれると想定して?す? 150 * サブクラスで、日本語??行う場合?方法?、それぞれ異なります? 151 * 152 * ※ ?で、UnsupportedEncodingException が発生した?合?、RuntimeException に変換されて throw されます? 153 * 154 * @param address String 155 * @param personal String 156 * 157 * @return InternetAddress 158 */ 159 public InternetAddress getAddress( final String address,final String personal ) { 160 try { 161 return new InternetAddress( address,personal,charset ); 162 } 163 catch( UnsupportedEncodingException ex ) { 164 String errMsg = "??エンコードが出来ません? 165 + "address=" + address + " , charset=" + charset ; 166 throw new RuntimeException( errMsg,ex ); 167 } 168 } 169 170 /** 171 * Content-Transfer-Encoding を指定する?合? ビット数を返します? 172 * 173 * Windows系は?bit / ISO-2022-JP 系は?bit になります? 174 * 175 * @return ビット数("8bit" 固? 176 */ 177 public String getBit() { 178 return "8bit" ; 179 } 180 } 181 182 /** 183 * MailCharset インターフェースを実??ISO-2022-JP エンコード時のサブクラスです? 184 * 185 * 『2.ISO-2022-JP に独自変換 + 7bit 送信?の実?す? 186 * 187 * @version 4.0 188 * @author Kazuhiko Hasegawa 189 * @since JDK5.0, 190 */ 191 static class Mail_ISO2022JP_Charset implements MailCharset { 192 193 /** 194 * プラ?フォー?存??ォルト? Charset です? 195 * プラ?フォー?存?を?慮する場合?エンコード指定で作?しておく事をお勧めします? 196 * 197 * @og.rev 5.5.2.6 (2012/05/25) findbugs対? 198 */ 199 private static final Charset DEFAULT_CHARSET = Charset.defaultCharset() ; 200 201 /** 202 * ?ストをセ?します? 203 * Part#setText() の代わりにこちらを使??します? 204 * 205 * ※ ?で、MessagingException が発生した?合?、RuntimeException に変換されて throw されます? 206 * 207 * @param mimeMsg MimeMessage 208 * @param text String 209 */ 210 public void setTextContent( final MimeMessage mimeMsg, final String text ) { 211 try { 212 // mimeMsg.setText(text, "ISO-2022-JP"); 213 mimeMsg.setDataHandler(new DataHandler(new JISDataSource(text))); 214 } 215 catch( MessagingException ex ) { 216 String errMsg = "???ストをセ?できません? 217 + "text=" + text ; 218 throw new RuntimeException( errMsg,ex ); 219 } 220 } 221 222 /** 223 * 日本語を含???用?ストを生?します? 224 * 変換結果は ASCII なので、これをそ?まま setSubject ?InternetAddress 225 * のパラメタとして使用してください? 226 * 227 * ※ ?で、UnsupportedEncodingException が発生した?合?、RuntimeException に変換されて throw されます? 228 * 229 * @param text String 230 * 231 * @return 日本語を含???用?ス? 232 */ 233 public String encodeWord( final String text ) { 234 try { 235 return "=?ISO-2022-JP?B?" + 236 new String( 237 BASE64EncoderStream.encode( 238 CharCodeConverter.sjisToJis( 239 UnicodeCorrecter.correctToCP932(text).getBytes("Windows-31J") 240 ) 241 ) 242 ,DEFAULT_CHARSET ) + "?="; // 5.5.2.6 (2012/05/25) findbugs対? 243 } 244 catch( UnsupportedEncodingException ex ) { 245 String errMsg = "??エンコードが出来ません? 246 + "text=" + text + " , charset=Windows-31J" ; 247 throw new RuntimeException( errMsg,ex ); 248 } 249 } 250 251 /** 252 * 日本語を含?ドレスを生成します? 253 * personal に、日本語が含まれると想定して?す? 254 * サブクラスで、日本語??行う場合?方法?、それぞれ異なります? 255 * 256 * ※ ?で、UnsupportedEncodingException が発生した?合?、RuntimeException に変換されて throw されます? 257 * 258 * @param address String 259 * @param personal String 260 * 261 * @return InternetAddress 262 */ 263 public InternetAddress getAddress( final String address,final String personal ) { 264 try { 265 return new InternetAddress( address,encodeWord( personal ) ); 266 } 267 catch( UnsupportedEncodingException ex ) { 268 String errMsg = "??エンコードが出来ません? 269 + "address=" + address ; 270 throw new RuntimeException( errMsg,ex ); 271 } 272 } 273 274 /** 275 * Content-Transfer-Encoding を指定する?合? ビット数を返します? 276 * 277 * Windows系は?bit / ISO-2022-JP 系は?bit になります? 278 * 279 * @return ビット数("7bit" 固? 280 */ 281 public String getBit() { 282 return "7bit" ; 283 } 284 } 285 286 /** 287 * ?スト?本?送信するための DataSource です? 288 * 289 * Windows-31J でバイトコードに変換した後?独自エンコードにて? 290 * Shift-JIS ?JIS 変換して?す? 291 * 292 * @version 4.0 293 * @author Kazuhiko Hasegawa 294 * @since JDK5.0, 295 */ 296 static class JISDataSource implements DataSource { 297 private final byte[] data; 298 299 public JISDataSource( final String str ) { 300 try { 301 data = CharCodeConverter.sjisToJis( 302 UnicodeCorrecter.correctToCP932(str).getBytes("Windows-31J")); 303 304 } catch (UnsupportedEncodingException e) { 305 String errMsg = "Windows-31J でのエンコー?ングが?来ません? + str; 306 throw new RuntimeException( errMsg,e ); 307 } 308 } 309 310 /** 311 * ??タの MIME タイプを??の形で返します? 312 * かならず有効なタイプを返すべきです? 313 * DataSource の実???タタイプを 決定できな??合?? 314 * getContentType は "application/octet-stream" を返すこと?提案します? 315 * 316 * @return MIME タイ? 317 */ 318 public String getContentType() { 319 return "text/plain; charset=ISO-2022-JP"; 320 } 321 322 /** 323 * ??タを表?InputStream を返します? 324 * それができな??合?適?例外をスローします? 325 * 326 * @return InputStream 327 * @throws IOException ※ こ?メソ?からは、IOException は throw されません? 328 */ 329 public InputStream getInputStream() throws IOException { 330 return new ByteArrayInputStream( data ); 331 } 332 333 /** 334 * ??タが書込可能な?OutputStream を返します? 335 * それができな??合?適?例外をスローします? 336 * 337 * ※ こ?クラスでは実?れて?せん? 338 * 339 * @return OutputStream 340 * @throws IOException ※ こ?メソ?を実行すると、? throw されます? 341 */ 342 public OutputStream getOutputStream() throws IOException { 343 String errMsg = "こ?クラスでは実?れて?せん?; 344 // throw new UnsupportedOperationException( errMsg ); 345 throw new IOException( errMsg ); 346 } 347 348 /** 349 * こ?オブジェクト? '名前' を返します? 350 * こ?名前は下層のオブジェクト?性質によります? 351 * ファイルをカプセル化す?DataSource な?オブジェクト? 352 * ファイル名を返すようにするかもしれません? 353 * 354 * @return オブジェクト?名前 355 */ 356 public String getName() { 357 return "JISDataSource"; 358 } 359 } 360 }