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 java.util.Map; 019import java.util.LinkedHashMap; 020import java.util.logging.Logger; 021import java.util.logging.Level; 022 023import org.opengion.fukurou.util.StringUtil ; 024import org.opengion.fukurou.util.HybsEntry ; 025import org.opengion.fukurou.util.Argument ; 026import org.opengion.fukurou.util.FileUtil ; // 6.4.5.2 (2016/05/06) 027import static org.opengion.fukurou.system.HybsConst.CR; // 6.3.8.0 (2015/09/11) 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=送信先アドレスをCSV形式で並べる(必須) 039 * -port=送信サーバーのポートを指定(初期値:-1) 040 * -useSSL=SSL接続するかどうか[true:する/false:しない]を指定(初期値:false:しない) 041 * -auth=認証方式(POP_BEFORE_SMTP , SMTP_AUTH のみ対応) 042 * -authPort=認証ポート(初期値:-1) 043 * -user=メールを取得するログインユーザー 044 * -passwd=メールを取得するログインパスワード 045 * -cc=関係者アドレスをCSV形式で並べる 046 * -bcc=隠し送信先アドレスをCSV形式で並べる 047 * -replyTo=返信先アドレスをCSV形式で並べる 048 * -subject=タイトル 049 * -message=本文を格納しているファイルのアドレス 050 * -msgEncode=本文を格納しているファイルの文字コード(初期値:java.nio.charset.Charset#defaultCharset()) 051 * -charset=メール送信時のキャラクタセット [ISO-2022-JP / Windows-31J] 052 * -fileXX=添付ファイルのファイルパス( XX は複数登録時の添え字 ) 053 * -debug=メイラーのデバッグモードを指定します。[false / true] 054 * -help=使用方法を出力して、終了します。 055 * -{@XXXX}=YYYY メッセージ本文の {@XXXX} 文字列を、YYYY 文字列に変換します。 056 * {@ARG.XXX} 予約文字変換 上記引数を割り当てます。 057 * {@DATE.XXX} 予約文字変換 SimpleDateFormat 形式の文字を変換します。(日付、時刻等) 058 * {@ENV.XXX} 予約文字変換 システムプロパティーの文字を変換します。(java -Dkey=value オプション) 059 * 060 * E-Mail で日本語を送信する場合、ISO-2022-JP(JISコード)化して、7bit で 061 * エンコードして送信する必要がありますが、Windows系の特殊文字や、unicodeと 062 * 文字のマッピングが異なる文字などが、文字化けします。 063 * 対応方法としては、 064 * 1.Windows-31J + 8bit 送信 065 * 2.ISO-2022-JP に独自変換 + 7bit 送信 066 * の方法があります。 067 * 今回、この2つの方法について、charset で指定できます。 068 * 初期値は、ISO-2022-JP です。 069 * 070 * ※ 6.2.4.1 (2015/05/22) SMTP_AUTH 対応 071 * 072 * ※ 6.3.8.0 (2015/09/11) 073 * useSSL属性=true に設定すると、protocolに、smtps を使用します。 074 * 075 * @version 4.0 076 * @author Kazuhiko Hasegawa 077 * @since JDK5.0, 078 */ 079public class MailTransfer { 080 // 6.3.9.1 (2015/11/27) The Logger variable declaration does not contain the static and final modifiers(PMD) 081 /** 6.8.1.0 (2017/07/14) クラス名を動的作成に変更 */ 082 private static final Logger LOGGER = Logger.getLogger( MailTransfer.class.getName() ); 083 084 /** メール送信時のデフォルトキャラクタセット 「={@value}」 */ 085 public static final String CHARSET = "ISO-2022-JP" ; 086 087 /** メイラーの初期デバッグモード 「={@value}」 */ 088 public static final boolean DEBUG_MODE = false ; 089 090 private Argument argment; // 6.3.8.0 (2015/09/11) 091 092 /** staticイニシャライザ後、読み取り専用にするので、ConcurrentHashMap を使用しません。 */ 093 private static final Map<String,String> MUST_PROPARTY ; // 必須パラメータ // 6.4.1.1 (2016/01/16) mustProparty → MUST_PROPARTY refactoring 094 /** staticイニシャライザ後、読み取り専用にするので、ConcurrentHashMap を使用しません。 */ 095 private static final Map<String,String> USABLE_PROPARTY ; // 整合性チェックパラメータ // 6.4.1.1 (2016/01/16) usableProparty → USABLE_PROPARTY refactoring 096 097 static { 098 MUST_PROPARTY = new LinkedHashMap<>(); 099 MUST_PROPARTY.put( "host", "メールサーバー(必須)" ); 100 MUST_PROPARTY.put( "from", "送信元アドレス(必須)" ); 101 MUST_PROPARTY.put( "to", "送信先アドレスをCSV形式で並べる(必須)" ); 102 103 USABLE_PROPARTY = new LinkedHashMap<>(); 104 USABLE_PROPARTY.put( "port" , "送信サーバーのポート" ); // 6.0.3.0 (2014/11/13) SMTP認証 105 USABLE_PROPARTY.put( "useSSL" , "SSL接続するかどうかを指定(初期値:false:しない)" ); // 6.3.8.0 (2015/09/11) 106 USABLE_PROPARTY.put( "useStarttls" , "STARTTLS接続するかどうかを指定(初期値:false:しない)" ); // 5.9.29.2 (2018/02/16) 107 USABLE_PROPARTY.put( "auth" , "認証方式(POP_BEFORE_SMTP , SMTP_AUTHのみ対応)" ); // 6.2.4.1 (2015/05/22) 108 USABLE_PROPARTY.put( "authPort" , "認証ポート" ); // 6.0.3.0 (2014/11/13) SMTP認証 109 USABLE_PROPARTY.put( "user" , "認証ユーザー" ); // 6.0.3.0 (2014/11/13) SMTP認証 110 USABLE_PROPARTY.put( "passwd" , "認証パスワード" ); // 6.0.3.0 (2014/11/13) SMTP認証 111 USABLE_PROPARTY.put( "cc" , "関係者アドレスをCSV形式で並べる" ); 112 USABLE_PROPARTY.put( "bcc" , "隠し送信先アドレスをCSV形式で並べる" ); 113 USABLE_PROPARTY.put( "replyTo" , "返信先アドレスをCSV形式で並べる" ); 114 USABLE_PROPARTY.put( "subject" , "タイトル" ); 115 USABLE_PROPARTY.put( "message" , "本文を格納しているファイルのアドレス" ); 116 USABLE_PROPARTY.put( "msgEncode" , "本文を格納しているファイルの文字コード [Windows-31J / UTF-8]" ); 117 USABLE_PROPARTY.put( "charset" , "メール送信時のキャラクタセット [ISO-2022-JP / Windows-31J]" ); 118 USABLE_PROPARTY.put( "file" , "添付ファイルのファイルパス( XX は複数登録時の添え字 )" ); 119 USABLE_PROPARTY.put( "{@" , "{@XXXX}=YYYY メッセージ本文の {@XXXX} 文字列を、YYYY 文字列に変換します。" ); 120 USABLE_PROPARTY.put( "{@ARG." , "{@ARG.XXX} 予約文字変換 上記引数を割り当てます。" ); 121 USABLE_PROPARTY.put( "{@DATE." , "{@DATE.XXX} 予約文字変換 SimpleDateFormat 形式の文字を変換します。(日付、時刻等)" ); 122 USABLE_PROPARTY.put( "{@ENV." , "{@ENV.XXX} 予約文字変換 システムプロパティーの文字を変換します。(java -Dkey=value オプション)" ); 123 USABLE_PROPARTY.put( "debug" , "メイラーのデバッグモードを指定します。[false / true]" ); 124 USABLE_PROPARTY.put( "help" , "使用方法を出力して、終了します。" ); 125 } 126 127 /** 128 * デフォルトコンストラクター 129 * 130 * @og.rev 8.5.3.2 (2023/10/13) JDK21対応。警告: デフォルトのコンストラクタの使用で、コメントが指定されていません 131 */ 132 public MailTransfer() { super(); } // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。 133 134 /** 135 * トランスファーを開始します。 136 * 137 * @og.rev 4.3.3.5 (2008/11/08) Argument オブジェクトへの引数を util → mail に訂正します。 138 * @og.rev 6.0.3.0 (2014/11/13) SMTP認証 139 * @og.rev 6.3.8.0 (2015/09/11) SSL接続するかどうかを指定するパラメータを追加します。 140 * @og.rev 6.3.8.0 (2015/09/11) message で指定されたファイルの 141 * @og.rev 6.4.5.1 (2016/04/28) FileStringのコンストラクター変更 142 * @og.rev 6.4.5.2 (2016/05/06) fukurou.util.FileString から、fukurou.util.FileUtil に移動。 143 * @og.rev 5.9.29.2 (2018/02/16) STARTTLS対応(キーワードをVer5 にあわせます) 144 * 145 * @param args 引数配列(可変長引数) 146 */ 147 public void start( final String... args ) { 148 149 // パラメータの解析、取得 150 LOGGER.fine( "パラメータの解析、取得" ); 151 argment = new Argument( "org.opengion.fukurou.mail.MailTransfer" ); // 4.3.3.5 (2008/11/08) 152 argment.setMustProparty( MUST_PROPARTY ); 153 argment.setUsableProparty( USABLE_PROPARTY ); 154 155 argment.setArgument( args ); 156 157 // help パラメータが true に指定された場合の処理。 158 if( argment.getProparty( "help",false ) ) { 159 System.out.println( argment.toString() ); 160 return; 161 } 162 163 final String host = argment.getProparty( "host" ); 164 final String chset = argment.getProparty( "charset", CHARSET ); 165 166 final boolean useSSL = argment.getProparty( "useSSL" ,false ); // 6.3.8.0 (2015/09/11) SSL接続 167 final boolean useStarttls = argment.getProparty( "useStarttls" ,false ); // 5.9.29.2 (2018/02/16) 168 169 final String port = argment.getProparty( "port" ); // 6.0.3.0 (2014/11/13) SMTP認証 170 final String auth = argment.getProparty( "auth" ); // 6.0.3.0 (2014/11/13) SMTP認証 171 final String authPort = argment.getProparty( "authPort" ); // 6.0.3.0 (2014/11/13) SMTP認証 172 final String user = argment.getProparty( "user" ); // 6.0.3.0 (2014/11/13) SMTP認証 173 final String passwd = argment.getProparty( "passwd" ); // 6.0.3.0 (2014/11/13) SMTP認証 174 175// final MailTX mail = new MailTX( host,chset,port,auth,authPort,user,passwd,useSSL ); // 6.3.8.0 (2015/09/11) SSL接続 176 final MailTX mail = new MailTX( host,chset,port,auth,authPort,user,passwd,useStarttls,useSSL ); // 6.3.8.0 (2015/09/11) SSL接続 177 LOGGER.fine( "org.opengion.fukurou.mail.MailTX の設定" ); 178 179 mail.setFrom( argment.getProparty( "from" ) ); 180 mail.setTo( StringUtil.csv2Array( argment.getProparty( "to" ) ) ); 181 mail.setCc( StringUtil.csv2Array( argment.getProparty( "cc" ) ) ); 182 mail.setBcc( StringUtil.csv2Array( argment.getProparty( "bcc" ) ) ); 183 mail.setReplyTo( StringUtil.csv2Array( argment.getProparty( "replyTo" ) ) ); 184 mail.setSubject( argment.getProparty( "subject" ) ); 185 mail.setDebug( argment.getProparty( "debug", DEBUG_MODE ) ); 186 187 // message は、本文を格納しているファイル名が指定されています。 188 final String msgFile = argment.getProparty( "message" ) ; 189 LOGGER.fine( "本文を格納しているファイルの取得。message=" + msgFile ); 190 if( msgFile != null ) { 191 final String msgEncode = argment.getProparty( "msgEncode" ) ; 192 // 6.4.5.1 (2016/04/28) FileStringのコンストラクター変更 193 String message = FileUtil.getValue( msgFile , msgEncode ); // 6.4.5.2 (2016/05/06) 194 195 // {@XXX} 変換は、Argument クラスの機能を使う。 196 message = argment.changeParam( message ); 197 mail.setMessage( message ); 198 } 199 200 // 添付ファイルは、fileXX 形式で、複数指定されています。 201 LOGGER.fine( "添付ファイルを取り込みます。" ); 202 final HybsEntry[] entry = argment.getEntrys( "file" ); 203 final String[] files = new String[entry.length]; // 8.5.4.2 (2024/01/12) PMD 7.0.0 LocalVariableCouldBeFinal 204 for( int i=0; i<files.length; i++ ) { 205 files[i] = entry[i].getValue() ; 206 } 207 mail.setFilename( files ); 208 209 // 送信 210 LOGGER.fine( "送信処理を行います。" ); 211 mail.sendmail(); 212 } 213 214 /** 215 * main メソッドです。 216 * 217 * @param args 引数配列 218 */ 219 public static void main ( final String[] args ) { 220 final MailTransfer transfer = new MailTransfer(); 221 try { 222 LOGGER.info( "メール送信処理を開始します ---------------------------------------------" ); 223 transfer.start( args ); 224 LOGGER.info( "正常に終了しました。" ); 225 } 226 catch( final Throwable th ) { 227 final String errMsg = "メール送信中に例外が発生しました。 " 228 + CR + transfer.argment 229 + CR + th.getMessage() ; 230 LOGGER.log( Level.SEVERE,errMsg, th ); 231 } 232 } 233}