    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}