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 org.opengion.fukurou.util.StringUtil ; 019 import org.opengion.fukurou.util.HybsEntry ; 020 import org.opengion.fukurou.util.LogWriter; 021 022 import java.util.Properties; 023 import java.util.List; 024 import java.util.ArrayList; 025 026 import javax.mail.Session; 027 import javax.mail.Store; 028 import javax.mail.Folder; 029 import javax.mail.Message; 030 import javax.mail.Flags; 031 import javax.mail.MessagingException; 032 import javax.mail.NoSuchProviderException; 033 import javax.mail.search.SearchTerm; 034 import javax.mail.search.SubjectTerm; 035 import javax.mail.search.FromStringTerm; 036 import javax.mail.search.BodyTerm; 037 import javax.mail.search.HeaderTerm; 038 import javax.mail.search.AndTerm; 039 040 /** 041 * MailRX は、POP3プロトコルによるメール受信プログラ?す? 042 * 043 * メールへの接続条件(host,user,passwd など)と?択条件(matchTermなど)を指定し? 044 * MailReceiveListener をセ?して、start() メソ?を呼びます? 045 * 実際のメール処??、MailReceiveListener を介して?メールずつ処?ます? 046 * 添付ファイルを??る?合?、MailAttachFiles クラスを使用します? 047 * 048 * host メールサーバ?(??) 049 * user メールを取得するログインユーザー(??) 050 * passwd メールを取得するログインパスワー???) 051 * protocol 受信サーバ?のプロトコル[imap/pop3]を指?初期値:pop3) 052 * port 受信サーバ?のポ?トを??初期値:-1) 053 * mbox 受信サーバ?のメールボックスを指?初期値:INBOX) 054 * maxRowCount 受信メールの?取り込み件数(初期値:100)(0:[無制限]) 055 * charset メールの?ォルトエンコー?初期値:ISO-2022-JP) 056 * matchTerm 受信メールを選択する条件のMINEntryオブジェク? 057 * delete 検索後?メールをサーバ?から削除するかど?を?true/falseで??初期値:false)? 058 * 059 * @version 4.0 060 * @author Kazuhiko Hasegawa 061 * @since JDK5.0, 062 */ 063 public class MailRX { 064 065 /** 受信メールの?取り込み件数を指定します? {@value} */ 066 public static final int MAX_ROW_COUNT = 100 ; 067 068 /** 検索後?メールをサーバ?から削除するかど?を?true/falseで?します? {@value} */ 069 public static final boolean DELETE_MESSAGE = false ; 070 071 /** メールサーバ?の?ォルト?ロトコル {@value} */ 072 public static final String PROTOCOL = "pop3" ; 073 074 /** メールサーバ?の?ォルト?ート番号 {@value} */ 075 public static final int PORT = -1 ; 076 077 /** メールサーバ?の?ォルトメールボックス {@value} */ 078 public static final String MBOX = "INBOX" ; 079 080 /** メールの?ォルトエンコー?{@value} 081 * Windwos-31J , MS932 , ISO-2022-JP を指定します? 082 */ 083 public static final String CHARSET = "ISO-2022-JP" ; 084 085 // メール受信毎に発生するイベントを伝えるリスナ?を登録します? 086 private MailReceiveListener listener = null; 087 088 private String host = null; 089 private String user = null; 090 private String passwd = null; 091 private String protocol = PROTOCOL; 092 private int port = PORT; 093 private String mbox = MBOX; 094 private boolean deleteFlag = DELETE_MESSAGE; 095 096 private String charset = CHARSET; 097 098 private int maxRowCount = MAX_ROW_COUNT; 099 private final List<HybsEntry> matchList = new ArrayList<HybsEntry>(); 100 private boolean debug = false; 101 102 /** 103 * レシーバ?を開始します? 104 * 105 */ 106 public void start() throws MessagingException,NoSuchProviderException { 107 108 // パラメータの解析?取? 109 debugMsg( "パラメータの解析?取? ); 110 111 // ??条件にマッチしたメ?ージのみ抜き出す為の、SearchTerm オブジェクト?作? 112 debugMsg( "??条件にマッチしたメ?ージのみ抜き出す条件を設定します?" ); 113 HybsEntry[] matchs = matchList.toArray( new HybsEntry[matchList.size()] ); 114 SearchTerm[] term = new SearchTerm[matchs.length]; 115 for( int i=0; i<matchs.length; i++ ) { 116 String key = matchs[i].getKey(); 117 if( "Subject".equalsIgnoreCase( key ) ) { 118 term[i] = new SubjectTerm( matchs[i].getValue() ); 119 } 120 else if( "From".equalsIgnoreCase( key ) ) { 121 term[i] = new FromStringTerm( matchs[i].getValue() ); 122 } 123 else if( "Body".equalsIgnoreCase( key ) ) { 124 term[i] = new BodyTerm( matchs[i].getValue() ); 125 } 126 else { 127 term[i] = new HeaderTerm( key,matchs[i].getValue() ); 128 } 129 } 130 SearchTerm srchTerm = new AndTerm( term ); 131 132 // 空の properties を設定?気休め程度に、?期?を設定しておきます? 133 debugMsg( "空の properties を設? ); 134 Properties prop = new Properties(); 135 prop.setProperty("mail.mime.charset", charset); 136 prop.setProperty("mail.mime.decodetext.strict", "false"); 137 prop.setProperty("mail.mime.address.strict", "false"); 138 139 // session を取? 140 debugMsg( "session を取? ); 141 Session session = Session.getInstance(prop, null); 142 143 Store store = null; 144 Folder folder = null; 145 try { 146 // store の取? 147 debugMsg( "store の取?protocol=",protocol ); 148 store = session.getStore( protocol ); 149 150 // サーバ?と connect します? 151 debugMsg( "サーバ?と connect します?" ); 152 store.connect(host, port, user, passwd); 153 154 // folder の取? 155 debugMsg( "folder の取? ); 156 folder = store.getFolder( mbox ); 157 if( deleteFlag ) { 158 folder.open(Folder.READ_WRITE); 159 } 160 else { 161 folder.open(Folder.READ_ONLY); 162 } 163 164 // メ?ージ??の取? 165 debugMsg( "メ?ージ??の取? ); 166 // Message[] message = folder.getMessages(); 167 Message[] message = folder.search( srchTerm ); 168 169 for(int i=0, n=message.length; i<n && i<maxRowCount; i++) { 170 MailMessage mailMessage = new MailMessage( message[i],host,user ); 171 debugMsg( "[" , String.valueOf(i) , "]" , mailMessage.getMessageID() , " 受信中" ); 172 173 // メールの削除[true/false]:先にフラグを立てて?ので、エラーでも削除されます? 174 message[i].setFlag(Flags.Flag.DELETED, deleteFlag); 175 176 boolean okFlag = true; 177 if( listener != null ) { 178 // メール本体?処? 179 okFlag = listener.receive( mailMessage ); 180 } 181 182 // 受?確認?返信メール 183 String notifyTo = mailMessage.getNotificationTo() ; 184 if( okFlag && notifyTo != null ) { 185 MailTX tx = new MailTX( host ); 186 tx.setFrom( user ); 187 tx.setTo( StringUtil.csv2Array( notifyTo ) ); 188 tx.setSubject( "受?:" + mailMessage.getSubject() ); 189 tx.setMessage( mailMessage.getContent() ); 190 tx.sendmail(); 191 } 192 } 193 } 194 finally { 195 // セ?ョン終? 196 debugMsg( "セ?ョン終??? ); 197 if( folder != null ) { 198 folder.close(deleteFlag); // true の場合?、終?に実際に削除します? 199 } 200 if( store != null ) { 201 store.close(); 202 } 203 } 204 } 205 206 /** 207 * メールサーバ?をセ?します? 208 * 209 * @param host メールサーバ? 210 * @throws IllegalArgumentException 引数?null の場合? 211 */ 212 public void setHost( final String host ) { 213 if( host == null ) { 214 String errMsg = "host に null はセ?出来ません?; 215 throw new IllegalArgumentException( errMsg ); 216 } 217 218 this.host = host; 219 } 220 221 /** 222 * 受信ユーザーをセ?します? 223 * 224 * @param user 受信ユーザー 225 * @throws IllegalArgumentException 引数?null の場合? 226 */ 227 public void setUser( final String user ) { 228 if( user == null ) { 229 String errMsg = "user に null はセ?出来ません?; 230 throw new IllegalArgumentException( errMsg ); 231 } 232 this.user = user; 233 } 234 235 /** 236 * パスワードをセ?します? 237 * 238 * @param passwd パスワー? 239 * @throws IllegalArgumentException 引数?null の場合? 240 */ 241 public void setPasswd( final String passwd ) { 242 if( passwd == null ) { 243 String errMsg = "passwd に null はセ?出来ません?; 244 throw new IllegalArgumentException( errMsg ); 245 } 246 this.passwd = passwd; 247 } 248 249 /** 250 * 受信プロトコルをセ?します? 251 * 252 * @param protocol 受信プロトコル? 253 * @throws IllegalArgumentException 引数?null の場合? 254 */ 255 public void setProtocol( final String protocol ) { 256 if( protocol == null ) { 257 String errMsg = "protocol に null はセ?出来ません?; 258 throw new IllegalArgumentException( errMsg ); 259 } 260 this.protocol = protocol; 261 } 262 263 /** 264 * ポ?ト番号をセ?します? 265 * 266 * @param port ポ?ト番号 267 */ 268 public void setPort( final int port ) { 269 this.port = port; 270 } 271 272 /** 273 * 受信メイルボックスをセ?します? 274 * 275 * @param mbox 受信メイルボックス? 276 * @throws IllegalArgumentException 引数?null の場合? 277 */ 278 public void setMbox( final String mbox ) { 279 if( mbox == null ) { 280 String errMsg = "mbox に null はセ?出来ません?; 281 throw new IllegalArgumentException( errMsg ); 282 } 283 this.mbox = mbox; 284 } 285 286 /** 287 * メール受信毎に発生するイベントを伝えるリスナ?をセ?します? 288 * 289 * @param listener MailReceiveリスナ? 290 */ 291 public void setMailReceiveListener( final MailReceiveListener listener ) { 292 this.listener = listener; 293 } 294 295 /** 296 * メ?ージをメールサーバ?から削除するかど?をセ?します? 297 * 298 * @param deleteFlag 削除するかど?[true:行う/false:行わない] 299 */ 300 public void setDelete( final boolean deleteFlag ) { 301 this.deleteFlag = deleteFlag; 302 } 303 304 /** 305 * ?エンコー?ングをセ?します? 306 * 307 * ?エンコー?ングには、Windwos-31J , MS932 , ISO-2022-JP を指定できます? 308 * 初期値は、SystemResource.properties ファイルの MAIL_DEFAULT_CHARSET 属?で 309 * 設定できます? 310 * 311 * @param charset ?エンコー?ング 312 * @throws IllegalArgumentException 引数?null の場合? 313 */ 314 public void setCharset( final String charset ) { 315 if( charset == null ) { 316 String errMsg = "charset に null はセ?出来ません?; 317 throw new IllegalArgumentException( errMsg ); 318 } 319 this.charset = charset; 320 } 321 322 /** 323 * ?取り込み件数をセ?しま?初期値:100)(0:[無制限])? 324 * 325 * @og.rev 5.5.8.5 (2012/11/27) 0を無制限として処?ます? 326 * 327 * @param maxRowCount ?取り込み件数 328 */ 329 public void setMaxRowCount( final int maxRowCount ) { 330 // this.maxRowCount = maxRowCount; 331 this.maxRowCount = ( maxRowCount > 0 ) ? maxRowCount : Integer.MAX_VALUE ; 332 } 333 334 /** 335 * メール検索する場合?マッチ条件のキーと値の HybsEntry をセ?します? 336 * Subject,From,Body,それ以外?、Header ??をキーにします? 337 * 338 * @param matchTerm HybsEntryオブジェク? 339 */ 340 public void addMatchTerm( final HybsEntry matchTerm ) { 341 matchList.add( matchTerm ); 342 } 343 344 /** 345 * ????の表示を行うかど?をセ?します? 346 * 347 * @param debug 有無[true/false] 348 */ 349 public void setDebug( final boolean debug ) { 350 this.debug = debug; 351 } 352 353 /** 354 * ????の表示を行います? 355 * 実際の処??、debug フラグに設定?によります? 356 * 357 * @param msgs String... 可変長メ?ージ 358 */ 359 private void debugMsg( final String... msgs ) { 360 if( debug ) { 361 for( String msg : msgs ) { 362 System.out.print( msg ); 363 } 364 System.out.println(); 365 } 366 } 367 368 /** 369 * コマンドから実行できる、テスト用の main メソ?です? 370 * 371 * java org.opengion.fukurou.mail.MailTX <from> <to> <host> <file> .... 372 * で、?の添付ファイルを?付することができます? 373 * 374 * @param args 引数配? 375 */ 376 public static void main( final String[] args ) throws Exception { 377 if(args.length < 3) { 378 LogWriter.log("Usage: java org.opengion.fukurou.mail.MailRX <host> <user> <passwd> [<saveDir>]"); 379 System.exit(1); 380 } 381 final String dir = (args.length == 4) ? args[3] : null; 382 383 MailRX recive = new MailRX(); 384 385 recive.setHost( args[0] ); 386 recive.setUser( args[1] ); 387 recive.setPasswd( args[2] ); 388 recive.setCharset( "ISO-2022-JP" ); 389 390 MailReceiveListener listener = new MailReceiveListener() { 391 public boolean receive( final MailMessage message ) { 392 System.out.println( message.getSimpleMessage() ); 393 394 if( dir != null ) { 395 message.saveSimpleMessage( dir ); 396 } 397 return true ; 398 } 399 }; 400 recive.setMailReceiveListener( listener ); 401 402 recive.start(); 403 } 404 }