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.StringUtil ;
019import org.opengion.fukurou.util.HybsEntry ;
020import org.opengion.fukurou.util.Argument ;
021import org.opengion.fukurou.util.FileString ;
022
023import java.util.Map;
024import java.util.LinkedHashMap;
025
026import java.util.logging.Logger;
027import java.util.logging.Level;
028
029/**
030 * MailTransfer は、SMTPプロトコルによるメール送信プログラムです。
031 *
032 * 引数には、host,from,to,cc,bcc,replyTo,subject,message,charset,file,debug,help が指定できます。
033 * 引数のプロパテイのキー部は、大文字・小文字が厳格に適用されますので、正確に記述願います。
034 *
035 * Usage: java org.opengion.fukurou.fukurou.mail.MailTransfer
036 *        -host=メールサーバー(必須)
037 *        -from=送信元アドレス(必須)
038 *        -to=送信先アドレスをカンマ区切りで並べる(必須)
039 *        -cc=関係者アドレスをカンマ区切りで並べる
040 *        -bcc=隠し送信先アドレスをカンマ区切りで並べる
041 *        -replyTo=返信先アドレスをカンマ区切りで並べる
042 *        -subject=タイトル
043 *        -message=本文を格納しているファイルのアドレス
044 *        -charset=メール送信時のキャラクタセット [ISO-2022-JP / Windows-31J]
045 *        -fileXX=添付ファイルのファイルパス( XX は複数登録時の添え字 )
046 *        -debug=メイラーのデバッグモードを指定します。[false / true]
047 *        -help=使用方法を出力して、終了します。
048 *        -{@XXXX}=YYYY  メッセージ本文の {@XXXX} 文字列を、YYYY 文字列に変換します。
049 *            {@ARG.XXX} 予約文字変換 上記引数を割り当てます。
050 *            {@DATE.XXX} 予約文字変換 SimpleDateFormat 形式の文字を変換します。(日付、時刻等)
051 *            {@ENV.XXX}  予約文字変換 システムプロパティーの文字を変換します。(java -Dkey=value オプション)
052 *
053 * E-Mail で日本語を送信する場合、ISO-2022-JP(JISコード)化して、7bit で
054 * エンコードして送信する必要がありますが、Windows系の特殊文字や、unicodeと
055 * 文字のマッピングが異なる文字などが、文字化けします。
056 * 対応方法としては、
057 * 1.Windows-31J + 8bit 送信
058 * 2.ISO-2022-JP に独自変換 + 7bit 送信
059 * の方法があります。
060 * 今回、この2つの方法について、charset で指定できます。
061 * 初期値は、ISO-2022-JP です。
062 *
063 * @version  4.0
064 * @author   Kazuhiko Hasegawa
065 * @since    JDK5.0,
066 */
067public class MailTransfer {
068        private static Logger logger = Logger.getLogger( "org.opengion.fukurou.fukurou.mail.MailTransfer" );            // 4.3.3.5 (2008/11/08)
069
070        /** メール送信時のデフォルトキャラクタセット {@value}  */
071        public static final String CHARSET = "ISO-2022-JP" ;
072
073        /** メイラーの初期デバッグモード {@value}  */
074        public static final boolean DEBUG_MODE = false ;
075
076        private static final Map<String,String> mustProparty   ;  // 必須パラメータ
077        private static final Map<String,String> usableProparty ;  // 整合性チェックパラメータ
078
079        static {
080                mustProparty = new LinkedHashMap<String,String>();
081                mustProparty.put( "host",       "メールサーバー(必須)" );
082                mustProparty.put( "from",       "送信元アドレス(必須)" );
083                mustProparty.put( "to",         "送信先アドレスをカンマ区切りで並べる(必須)" );
084
085                usableProparty = new LinkedHashMap<String,String>();
086                usableProparty.put( "cc",               "関係者アドレスをカンマ区切りで並べる" );
087                usableProparty.put( "bcc",              "隠し送信先アドレスをカンマ区切りで並べる" );
088                usableProparty.put( "replyTo",  "返信先アドレスをカンマ区切りで並べる" );
089                usableProparty.put( "subject",  "タイトル" );
090                usableProparty.put( "message",  "本文を格納しているファイルのアドレス" );
091                usableProparty.put( "charset",  "メール送信時のキャラクタセット [ISO-2022-JP / Windows-31J]" );
092                usableProparty.put( "file",             "添付ファイルのファイルパス( XX は複数登録時の添え字 )" );
093                usableProparty.put( "{@",               "{@XXXX}=YYYY  メッセージ本文の {@XXXX} 文字列を、YYYY 文字列に変換します。" );
094                usableProparty.put( "{@ARG.",   "{@ARG.XXX} 予約文字変換 上記引数を割り当てます。" );
095                usableProparty.put( "{@DATE.",  "{@DATE.XXX} 予約文字変換 SimpleDateFormat 形式の文字を変換します。(日付、時刻等)" );
096                usableProparty.put( "{@ENV.",   "{@ENV.XXX} 予約文字変換 システムプロパティーの文字を変換します。(java -Dkey=value オプション)" );
097                usableProparty.put( "debug",    "メイラーのデバッグモードを指定します。[false / true]" );
098                usableProparty.put( "help",             "使用方法を出力して、終了します。" );
099        }
100
101        /**
102         * トランスファーを開始します。
103         *
104         * @og.rev 4.3.3.5 (2008/11/08) Argument オブジェクトへの引数を util → mail に訂正します。
105         *
106         * @param       args    引数配列
107         */
108        public void start( final String[] args ) {
109
110                // パラメータの解析、取得
111                logger.fine( "パラメータの解析、取得" );
112                Argument argment = new Argument( "org.opengion.fukurou.mail.MailTransfer" );            // 4.3.3.5 (2008/11/08)
113                argment.setMustProparty( mustProparty );
114                argment.setUsableProparty( usableProparty );
115
116                argment.setArgument( args );
117
118                // help パラメータが true に指定された場合の処理。
119                if( argment.getProparty( "help",false ) ) {
120                        System.out.println( argment.toString() );
121                        return;
122                }
123
124                String host  = argment.getProparty( "host" );
125                String chset = argment.getProparty( "charset", CHARSET );
126
127                MailTX mail = new MailTX( host,chset );
128                logger.fine( "org.opengion.fukurou.mail.MailTX の設定" );
129
130                mail.setFrom( argment.getProparty( "from" ) );
131                mail.setTo( StringUtil.csv2Array( argment.getProparty( "to" ) ) );
132                mail.setCc( StringUtil.csv2Array( argment.getProparty( "cc" ) ) );
133                mail.setBcc( StringUtil.csv2Array( argment.getProparty( "bcc" ) ) );
134                mail.setReplyTo( StringUtil.csv2Array( argment.getProparty( "replyTo" ) ) );
135                mail.setSubject( argment.getProparty( "subject" ) );
136                mail.setDebug( argment.getProparty( "debug", DEBUG_MODE ) );
137
138                // message は、本文を格納しているファイル名が指定されています。
139                String msgFile = argment.getProparty( "message" ) ;
140                logger.fine( "本文を格納しているファイルの取得。message=" + msgFile );
141                if( msgFile != null ) {
142                        FileString fs = new FileString();
143                        fs.setFilename( msgFile );
144                        String message = fs.getValue();
145
146                        // {@XXX} 変換は、Argument クラスの機能を使う。
147                        message = argment.changeParam( message );
148                        mail.setMessage( message );
149                }
150
151                // 添付ファイルは、fileXX 形式で、複数指定されています。
152                logger.fine( "添付ファイルを取り込みます。" );
153                HybsEntry[] entry = argment.getEntrys( "file" );
154                String[] files = new String[entry.length];
155                for( int i=0; i<files.length; i++ ) {
156                        files[i] = entry[i].getValue() ;
157                }
158                mail.setFilename( files );
159
160                // 送信
161                logger.fine( "送信処理を行います。" );
162                mail.sendmail();
163        }
164
165        /**
166         * main メソッドです。
167         *
168         * @param       args    引数配列
169         */
170        public static void main ( final String[] args ) {
171                MailTransfer transfer = new MailTransfer();
172                try {
173                        logger.info( "メール送信処理を開始します  ---------------------------------------------" );
174                        transfer.start( args );
175                        logger.info( "正常に終了しました。" );
176                }
177                catch( Throwable th ) {
178                        String errMsg = "メール送信中に例外が発生しました。 ";
179                        logger.log( Level.SEVERE,errMsg, th );
180                        throw new RuntimeException( errMsg,th );        // 4.0.0 (2005/01/31)
181                }
182        }
183}