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 */ 016package org.opengion.fukurou.mail; 017 018import org.opengion.fukurou.util.HybsEntry ; 019import org.opengion.fukurou.util.Argument ; 020import org.opengion.fukurou.util.LogWriter; 021 022import java.util.Map; 023import java.util.LinkedHashMap; 024 025import java.util.logging.Logger; 026import java.util.logging.Level; 027import javax.mail.MessagingException ; 028 029/** 030 * MailReceiver は、POP3プロトコルによるメール受信プログラムです。 031 * 032 * 引数には、host,user,passwd,headerList,mailSaveDir,fileSaveDir,filter,help が指定できます。 033 * メールは、メッセージID名をファイル名として、セーブします。 034 * 添付ファイルは、元のファイル名で、指定のディレクトリに出力される為、複数のメールを 035 * 同時に抜く場合は、uniq 属性を付与してください。その場合は、メッセージID+連番+元のファイル名 036 * で、ファイルをセーブします。添付ファイルには、同名のファイルを複数添付することが 037 * できるため、保存時には、添付ファイルの番号を連番としてファイル名に、付与します。 038 * 039 * 引数のプロパテイのキー部は、大文字・小文字が厳格に適用されますので、正確に記述願います。 040 * 041 * Usage: java org.opengion.fukurou.fukurou.mail.MailReceiver 042 * -host=メールサーバー(必須) 043 * -user=メールを取得するログインユーザー(必須) 044 * -passwd=メールを取得するログインパスワード(必須) 045 * -protocol=受信サーバーのプロトコル[imap/pop3]を指定(初期値:pop3) 046 * -port=受信サーバーのポートを指定(初期値:-1) 047 * -mailSaveDir=受信メールをセーブするディレクトリ。指定がない場合は、標準出力へ出力する。 048 * -fileSaveDir=添付ファイルをセーブするディレクトリ。指定がない場合は抜き出さない。 049 * -useMsgId=添付ファイルをセーブするディレクトリに、MesssageIdフォルダを個別に割り当てるかどうか(初期値:false) 050 * -maxRowCount=受信メールの最大取り込み件数(初期値:100)(0:[無制限]) 051 * -match_Subject=受信メールのSubjectを選択する条件 052 * -match_Body=受信メールのBodyを選択する条件 053 * -match_From=受信メールのFromを選択する条件 054 * -match_XXXX=受信メールのヘッダー部のキーXXXXを選択する条件 055 * -delete=検索後、メールをサーバーから削除するかどうかを、true/falseで指定(初期値:false) 056 * -help=使用方法を出力して、終了します。 057 * 058 * @version 0.9.0 2000/11/13 059 * @author Kazuhiko Hasegawa 060 * @since JDK5.0, 061 */ 062public class MailReceiver { 063 private static Logger logger = Logger.getLogger( "org.opengion.fukurou.fukurou.mail.MailReceiver" ); // 4.3.3.5 (2008/11/08) 064 065 private static final String CR = System.getProperty("line.separator"); 066 067 /** 受信メールの最大取り込み件数を指定します。 {@value} */ 068 public static final int MAX_ROW_COUNT = 100 ; 069 070 /** 検索後、メールをサーバーから削除するかどうかを、true/falseで指定します。 {@value} */ 071 public static final boolean DELETE_MESSAGE = false ; 072 073 /** メールサーバーのデフォルトプロトコル {@value} */ 074 public static final String PROTOCOL = "pop3" ; 075 076 /** メールサーバーのデフォルトポート番号 {@value} */ 077 public static final int PORT = -1 ; 078 079 private Argument argment = null; 080 081 private static final Map<String,String> mustProparty ; 082 private static final Map<String,String> usableProparty ; 083 084 static { 085 mustProparty = new LinkedHashMap<String,String>(); 086 mustProparty.put( "host", "メールサーバー(必須)" ); 087 mustProparty.put( "user", "メールを取得するログインユーザー(必須)" ); 088 mustProparty.put( "passwd", "メールを取得するログインパスワード(必須)" ); 089 090 usableProparty = new LinkedHashMap<String,String>(); 091 usableProparty.put( "protocol", "受信サーバーのプロトコル(imap,pop3)を指定(初期値:pop3)" ); 092 usableProparty.put( "port", "受信サーバーのポートを指定(初期値:-1)" ); 093 usableProparty.put( "mailSaveDir", "受信メールをセーブするディレクトリ。" + 094 CR + "指定がない場合は、標準出力へ出力する。" ); 095 usableProparty.put( "fileSaveDir", "添付ファイルをセーブするディレクトリ。" + 096 CR + "指定がない場合は抜き出さない。" ); 097 usableProparty.put( "useMsgId", "添付ファイルをセーブするディレクトリに、" + 098 CR + "MesssageIdフォルダを個別に割り当てるかどうか。" ); 099 usableProparty.put( "maxRowCount", "受信メールの最大取り込み件数(初期値:100)(0:[無制限])" ); 100 usableProparty.put( "match_Subject", "受信メールのSubjectを選択する条件" ); 101 usableProparty.put( "match_Body", "受信メールのBodyを選択する条件" ); 102 usableProparty.put( "match_From", "受信メールのFromを選択する条件" ); 103 usableProparty.put( "match_", "受信メールのヘッダー部のキーXXXXを選択する条件" ); 104 usableProparty.put( "delete", "検索後、メールをサーバーから削除するかどうかを、" + 105 CR + "true/falseで指定(初期値:false)" ); 106 usableProparty.put( "help", "使用方法を出力して、終了します。" ); 107 } 108 109 /** 110 * レシーバーを開始します。 111 * 112 * @og.rev 4.3.3.5 (2008/11/08) Argument オブジェクトへの引数を util → mail に訂正します。 113 * 114 * @param args 引数配列 115 * @throws MessagingException なんらかのエラーが発生した場合。 116 */ 117 public void start( final String[] args ) throws MessagingException { 118 119 // パラメータの解析、取得 120 logger.fine( "パラメータの解析、取得" ); 121 argment = new Argument( "org.opengion.fukurou.fukurou.mail.MailReceiver" ); // 4.3.3.5 (2008/11/08) 122 argment.setMustProparty( mustProparty ); 123 argment.setUsableProparty( usableProparty ); 124 125 argment.setArgument( args ); 126 127 // help パラメータが true に指定された場合の処理。 128 if( argment.getProparty( "help",false ) ) { 129 System.out.println( argment.toString() ); 130 return; 131 } 132 133 // 処理に必要な各種パラメータを取得しておきます。 134 logger.fine( "処理に必要な各種パラメータを取得します。" ); 135 MailRX recive = new MailRX(); 136 137 recive.setHost( argment.getProparty( "host" ) ) ; 138 recive.setUser( argment.getProparty( "user" ) ) ; 139 recive.setPasswd( argment.getProparty( "passwd" ) ) ; 140 recive.setProtocol( argment.getProparty( "protocol",PROTOCOL ) ) ; 141 recive.setPort( argment.getProparty( "port",PORT ) ) ; 142 recive.setDelete( argment.getProparty( "delete",DELETE_MESSAGE ) ) ; 143 recive.setMaxRowCount( argment.getProparty( "maxRowCount",MAX_ROW_COUNT ) ) ; 144 145 // 指定の条件にマッチしたメッセージのみ抜き出す為の、SearchTerm オブジェクトの作成 146 logger.fine( "指定の条件にマッチしたメッセージのみ抜き出す条件を設定します。" ); 147 HybsEntry[] matchs = argment.getEntrys( "match_" ); 148 for( int i=0; i<matchs.length; i++ ) { 149 recive.addMatchTerm( matchs[i] ) ; 150 } 151 152 // リスナーを設定して、受信メールを一件ずつ処理します。 153 logger.fine( "リスナーを設定して、受信メールを一件ずつ処理します。" ); 154 String mailSaveDir = argment.getProparty( "mailSaveDir" ); 155 String fileSaveDir = argment.getProparty( "fileSaveDir" ); 156 boolean useMsgId = argment.getProparty( "useMsgId",false ); 157 158 MailReceiveListener listener = new ReceiveListener( mailSaveDir,fileSaveDir,useMsgId ) ; 159 recive.setMailReceiveListener( listener ); 160 161 recive.start(); 162 } 163 164 /** 165 * メール受信プログラムで使用する MailReceiveListener の実装内部クラスです。 166 * 167 * @version 0.9.0 2000/11/13 168 * @author Kazuhiko Hasegawa 169 * @since JDK5.0, 170 */ 171 private static class ReceiveListener implements MailReceiveListener { 172 private final String mailSaveDir ; 173 private final String fileSaveDir ; 174 private final boolean useMsgId ; 175 private int counter = 0; 176 177 /** 178 * コンストラクター 179 * 180 * @param mailSaveDir メールをセーブする場合の保存フォルダ名 181 * @param fileSaveDir メールの添付ファイルをセーブする場合の保存フォルダ名 182 * @param useMsgId 添付ファイルをセーブする場合に、メッセージIDを使用するかどうか 183 */ 184 public ReceiveListener( final String mailSaveDir,final String fileSaveDir,final boolean useMsgId ) { 185 this.mailSaveDir = mailSaveDir; 186 this.fileSaveDir = fileSaveDir; 187 this.useMsgId = useMsgId; 188 } 189 190 /** 191 * 受信処理を行います。 192 * 193 * @param message MailMessage 194 * @return 結果(true:正常/false:異常) 195 */ 196 public boolean receive( final MailMessage message ) { 197 String msg = "[" + counter++ + "]" + message.getMessageID() + " 受信中" ; 198 System.out.println( msg ); 199 200 if( mailSaveDir != null ) { 201 message.saveMessage( mailSaveDir ); 202 } 203 else { 204 System.out.println( message.getSubject() ); 205 System.out.println( message.getContent() ); 206 } 207 208 if( fileSaveDir != null ) { 209 message.saveAttachFiles( fileSaveDir,useMsgId ); 210 } 211 return true ; 212 } 213 } 214 215 /** 216 * main メソッドです。 217 * 218 * @param args コマンド引数配列 219 */ 220 public static void main ( final String[] args ) { 221 MailReceiver receiver = new MailReceiver(); 222 try { 223 logger.info( "メール受信処理を開始します ---------------------------------------------" ); 224 receiver.start( args ); 225 logger.info( "正常に終了しました。" ); 226 } 227 catch( Throwable th ) { 228 String errMsg = "メール受信中に例外が発生しました。 " 229 + CR + receiver.argment 230 + CR + th.getMessage() ; 231 LogWriter.log( errMsg ); 232 logger.log( Level.SEVERE,errMsg, th ); 233 throw new RuntimeException( errMsg,th ); // 4.0.0 (2005/01/31) 234 } 235 } 236}