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.hayabusa.mail;
017
018import static org.opengion.fukurou.util.StringUtil.nval;
019
020import java.util.List;
021import java.util.ArrayList;
022import java.util.HashMap;
023import java.util.Map;
024
025import javax.mail.Address;
026import javax.mail.SendFailedException;
027import javax.mail.internet.InternetAddress;
028
029import org.opengion.fukurou.db.DBUtil;
030import org.opengion.fukurou.mail.MailTX;
031import org.opengion.fukurou.util.ApplicationInfo;
032import org.opengion.hayabusa.common.HybsSystem;
033
034/**
035 * タグ mailSender2 及びバッチによる送信の共通処理部分を実装しています。
036 * 送信タグ mailSender2 もしくは送信デーモンからパラメータを受取ります。
037 * パラメータ中の定型文ID及びシステムIDで定型文マスタよりメールの定型文を取得して、
038 * パラメータ値とマージしてメール文を合成します。同時に、宛先にセットした社員ID、
039 * グループIDと定型文の宛先設定に基づき、社員マスタとグループマスタよりメールアドレス
040 * 情報を取得して送信を行います。
041 * エラーがなければ送信した内容を履歴テーブル、宛先テーブルに書き込みます。
042 * 最後に本処理の呼出元に送信結果、エラーメッセージを返します。
043 *
044 * @og.group メールモジュール
045 *
046 * @version  4.0
047 * @author   Sen.Li
048 * @since    JDK1.6
049 */
050public abstract class AbstractMailManager {
051
052        // 5.2.0.0 (2010/09/01) Ver4互換モード対応
053        private static final String CONTENTS = HybsSystem.sysBool( "VER4_COMPATIBLE_MODE" ) ? "CONTENT" : "CONTENTS";
054
055        private static final String     selYkno = "SELECT GE32S02.NEXTVAL YKNO FROM DUAL";
056        // 5.0.3.0 (2009/11/04) CONTENT ⇒ CONTENTS
057        // 5.2.0.0 (2010/09/01) Ver4互換モード対応
058        private static final String     insGE32         = "INSERT INTO GE32(YKNO,PARA_KEY,PTN_ID,FROM_ADDR,TITLE,"+CONTENTS+",ATTACH1,ATTACH2,ATTACH3,ATTACH4,ATTACH5,DYSET,USRSET,PGUPD,SYSTEM_ID,FGJ)"
059                                                                                        + " VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,'1')";
060        private static final String insGE34             = "INSERT INTO GE34(YKNO,DST_ID,GROUP_ID,DST_NAME,DST_ADDR,DST_KBN,FGJ,DYSET,USRSET,PGUPD)"
061                                                                                        + " VALUES(?,?,?,?,?,?,?,?,?,?)";
062        /** フラグ定数 {@value} */
063        protected static final String FGJ_SEND_WAIT     = "0";
064        /** フラグ定数 {@value} */
065        protected static final String FGJ_SEND_OVER     = "1";
066        /** フラグ定数 {@value} */
067        protected static final String FGJ_ADDR_ERR      = "7";
068        /** フラグ定数 {@value} */
069        protected static final String FGJ_ACNT_ERR      = "8";
070
071        // 内部データのカラム番号(履歴テーブル)
072        private static final int GE32_YKNO              = 0 ;
073        private static final int GE32_PARAKEY   = 1 ;
074        private static final int GE32_PTN_ID    = 2;
075        private static final int GE32_FROM_ADDR = 3;
076        private static final int GE32_TITLE     = 4;
077        private static final int GE32_CONTENTS  = 5;            // 5.0.3.0 (2009/11/04) CONTENT ⇒ CONTENTS
078        private static final int GE32_ATTACH1   = 6;
079        private static final int GE32_ATTACH2   = 7;
080        private static final int GE32_ATTACH3   = 8;
081        private static final int GE32_ATTACH4   = 9;
082        private static final int GE32_ATTACH5   = 10;
083        private static final int GE32_DYSET             = 11;
084        private static final int GE32_USRSET    = 12;
085        private static final int GE32_PGUPD     = 13;
086        private static final int GE32_SYSTEM_ID = 14;
087        // 内部データのカラム番号(履歴テーブル)
088        private static final int GE34_YKNO              = 0 ;
089        private static final int GE34_DST_ID    = 1 ;
090        private static final int GE34_GROUP_ID  = 2 ;
091        private static final int GE34_DST_NAME  = 3 ;
092        private static final int GE34_DST_ADDR  = 4 ;
093        private static final int GE34_DST_KBN   = 5 ;
094        private static final int GE34_FGJ               = 6 ;
095        private static final int GE34_DYSET             = 7 ;
096        private static final int GE34_USRSET    = 8 ;
097        private static final int GE34_PGUPD     = 9 ;
098 //     private static String           host            = HybsSystem.sys( "COMMON_MAIL_SERVER" );
099        private static String           charset         = HybsSystem.sys( "MAIL_DEFAULT_CHARSET" );
100 //     private static String           smtpPort        = HybsSystem.sys( "SMTP_PORT" );                                // 5.4.3.2 (2012/01/06)
101 //     private static String           auth            = HybsSystem.sys( "MAIL_SEND_AUTH" );                   // 5.4.3.2 (2012/01/06)
102 //     private static String           authUser        = HybsSystem.sys( "MAIL_SEND_AUTH_USER" );              // 5.4.3.2 (2012/01/06)
103 //     private static String           authPass        = HybsSystem.sys( "MAIL_SEND_AUTH_PASSWORD" );  // 5.4.3.2 (2012/01/06)
104        private boolean                         debugFlag   = false;
105        private final List<String>      errAddrList = new ArrayList<String>();
106        private static final int MAX_RETRY              = 3 ;   // メールアドレスエラー発生した場合、メール再送回数
107
108        // 5.6.6.0 (2013/07/05) host等の外部指定に対応
109        private String          host            = HybsSystem.sys( "COMMON_MAIL_SERVER" );               // 5.6.6.0 (2013/07/05)
110        private String          smtpPort        = HybsSystem.sys( "SMTP_PORT" );                                // 5.6.6.0 (2013/07/05)
111        private String          auth            = HybsSystem.sys( "MAIL_SEND_AUTH" );                   // 5.6.6.0 (2013/07/05)
112        private String          authUser        = HybsSystem.sys( "MAIL_SEND_AUTH_USER" );              // 5.6.6.0 (2013/07/05)
113        private String          authPass        = HybsSystem.sys( "MAIL_SEND_AUTH_PASSWORD" );  // 5.6.6.0 (2013/07/05)
114
115        private String  mailTitle, mailContent, fromAddr;
116        private String[] attachFiles;
117        private Map<String, String[]>   mailDstMap              = null;
118        private Map<String,String>              initParamMap    = null;         // パラメータマップ
119        private MailTX                                  mail                    = null;
120
121        protected final String DBID = HybsSystem.sys( "RESOURCE_DBID" );                // 5.5.5.1 (2012/08/07) リソース系DBID 付け忘れ対応
122
123        /** コネクションにアプリケーション情報を追記するかどうか指定 */
124        private static final boolean USE_DB_APPLICATION_INFO  = HybsSystem.sysBool( "USE_DB_APPLICATION_INFO" ) ;
125
126        /** アプリケーション情報 */
127        public static final ApplicationInfo appInfo;
128        static {
129                if( USE_DB_APPLICATION_INFO ) {
130                        appInfo = new ApplicationInfo();
131                        // ユーザーID,IPアドレス,ホスト名
132                        appInfo.setClientInfo( "MailModuel", HybsSystem.HOST_ADRS, HybsSystem.HOST_NAME );
133                        // 画面ID,操作,プログラムID
134                        appInfo.setModuleInfo( "MailModuel", "MailManager", "MailManager" );
135                }
136                else {
137                        appInfo = null;
138                }
139        }
140
141        /**
142         * 呼出元よりパラメータマップを受取って、メールオブジェクト(mailObj)を作成します。
143         * メールオブジェクトは定型文ID及びシステムIDに基づいて定型文マスタからメールの定型文を取得して、
144         * パラメータ値とマージしてメール文の各項目を合成します。
145         * 宛先については、宛先にセットした社員ID、グループIDと定型文の宛先設定に基づき、社員マスタとグループマスタ
146         * よりメールアドレスを取得して宛先マップを作成します。
147         * まだ、添付ファイルのセット処理も行っています。
148         * 
149         * @og.rev 5.6.6.0 (2013/07/05) host等の外部設定対応
150         *
151         * @param       params  パラメータのマップ
152         */
153        public void create( final Map<String, String> params ) {
154                initParamMap = params;
155                MailPattern mailObj = new MailPattern( params );
156                fromAddr = mailObj.getFromAddr();
157                setAttachFiles( params.get( "ATTACH1" )
158                                          , params.get( "ATTACH2" )
159                                          , params.get( "ATTACH3" )
160                                          , params.get( "ATTACH4" )
161                                          , params.get( "ATTACH5" ) ); // 添付ファイルのセット
162                mailDstMap = mailObj.getDstMap();
163                mailTitle = mailObj.getTitle();
164                mailContent = mailObj.getContent();
165                errAddrList.addAll( mailObj.getErrList() );
166                
167                // 5.6.6.0 (2013/07/05)
168                host            = nval( mailObj.getHost()               ,host           );
169                smtpPort        = nval( mailObj.getSmtpPort()   ,smtpPort       );
170                auth            = nval( mailObj.getAuth()               ,auth           );
171                authUser        = nval( mailObj.getAuthUser()   ,authUser       );
172                authPass        = nval( mailObj.getAuthPass()   ,authPass       );
173        }
174
175        /**
176         * メール送信を行うメソッドです。
177         * createメソッドより合成した内容で送信を行います。アドレスエラー発生時に、
178         * ユーザー設定(addrCheck)により再送/中止します。
179         * メールサーバーに送信して、例外"SendFailedException"をキャッチできたら、
180         * メールアカウントがエラーとなるのを分かります。そして、例外のオブジェクトから
181         * エラーとなっているアカウントを取得して宛先マップから除外して、残りのアドレスに再送できます。
182         * 送信後履歴テーブル(GE32)、宛先テーブル(GE34)に送信結果を書き込みます。
183         *
184         * og.rev 5.4.3.2 (2012/01/06) 送信時認証対応
185         *
186         */
187        public void send() {
188                List<String> invalidAddrBuf     = new ArrayList<String>();
189                // mail = new MailTX( host, charset );
190                mail = new MailTX( host, charset, smtpPort, auth, authUser, authPass ); // 5.4.3.2 認証対応
191                mail.setFrom( fromAddr );                       // 送信者アドレス
192                mail.setFilename( attachFiles );        // 添付ファイルをセットします。
193                mail.setSubject( mailTitle );           // メールタイトル
194                mail.setMessage( mailContent );         // メール本文
195                mail.setDebug( debugFlag );
196                setMailDst( invalidAddrBuf );           // 宛先をセットします。
197                // メール送信を行います。
198                int retryCount = MAX_RETRY;
199                while( retryCount > 0 ) {
200                        try {
201                                mail.sendmail();
202                        }
203                        catch( RuntimeException rex ) {
204                                Throwable cause = rex.getCause();
205                                if( cause instanceof SendFailedException ) {
206                                        Address[] invAddress = ( (SendFailedException) cause ).getInvalidAddresses();
207                                        if( invAddress != null ) {
208                                                int invCount = invAddress.length;
209                                                for( int i = 0; i < invCount; i++ ) {
210                                                        invalidAddrBuf.add( ( (InternetAddress) invAddress[i] ).getAddress() );
211                                                }
212                                        }
213                                }
214                                else {
215                                        String errMsg = "送信時にエラー発生しました。" + rex.getMessage();
216                                        throw new RuntimeException( errMsg,rex );
217                                }
218                        }
219
220                        if( invalidAddrBuf.isEmpty() ) {
221                                retryCount = -1;
222                        }
223                        else {
224                                StringBuilder errMsgBuf = new StringBuilder();
225                                for( int i = 0; i < invalidAddrBuf.size(); i++ ) {
226                                        errMsgBuf.append( ',' ).append( invalidAddrBuf.get( i ) );
227                                }
228                                String userIds = getUserIds( invalidAddrBuf );
229                                String errMsg = "アドレスエラー。ユーザーID:" + userIds + " アドレス:" + errMsgBuf.toString().substring( 1 );
230                                if( "true".equals( initParamMap.get( "ADDR_CHECK" ) ) ){
231                                        throw new RuntimeException( errMsg );
232                                }
233                                else {
234                                        // メールアカウントチェックしない場合、無効のメールアドレスを除いて再送します。
235                                        setMailDst( invalidAddrBuf );
236                                        retryCount--;
237                                        invalidAddrBuf.clear();
238                                        errAddrList.add( errMsg );
239                                }
240                        }
241                }
242                commitMailDB();         // 送信結果を履歴テーブル、宛先テーブルにセットします。
243        }
244
245        /**
246         * デバッグ情報の表示を行うかどうか[true/false]をセットします。
247         *
248         * @param   debug  [true:出力する/それ以外:しない]
249         */
250        public void setDebug( final boolean debug ) {
251                debugFlag = debug;
252        }
253
254        /**
255         * メール送信者アドレスをセットします。
256         *
257         * @param  from 送信者アドレス
258         */
259        public void setFromAddr( final String from ) {
260                fromAddr = from;
261        }
262
263        /**
264         * メールタイトルをセットします。
265         *
266         * @param  title メールタイトル
267         */
268        public void setTitle( final String title ) {
269                mailTitle = title;
270        }
271
272        /**
273         * メール本文をセットします。
274         *
275         * @param  content メール本文
276         */
277        public void setContent( final String content ) {
278                mailContent = content;
279        }
280
281        /**
282         * メール送信ホストをセットします。
283         * 初期値は、システム定数のCOMMON_MAIL_SERVER を使用します。
284         *
285         * (初期値:システム定数のCOMMON_MAIL_SERVER[={@og.value org.opengion.hayabusa.common.SystemData#COMMON_MAIL_SERVER}])。
286         * 
287         * @og.rev 5.6.6.0 (2013/07/05)
288         *
289         * @param  hostName 送信ホスト
290         */
291        public void setHost( final String hostName ) {
292                host = nval( hostName, host );
293        }
294
295        /**
296         * メール送信ポート番号をセットします。
297         * 初期値は、システム定数のSMTP_PORT を使用します。
298         *
299         * (初期値:システム定数のSMTP_PORT[={@og.value org.opengion.hayabusa.common.SystemData#SMTP_PORT}])。
300         * 
301         * @og.rev 5.6.6.0 (2013/07/05)
302         * 
303         * @param  port SMTPポート
304         */
305        public void setPort( final String port ) {
306                smtpPort = nval( port, smtpPort );
307        }
308
309        /**
310         * メール送信時認証有無をセットします。
311         * 認証を行う場合は「POP_BEFORE_SMTP」と指定して下さい。
312         * 認証時には認証ユーザと認証パスワードを設定する必要があります。
313         * 初期値は、システム定数のMAIL_SEND_AUTH を使用します。
314         *
315         * (初期値:システム定数のMAIL_SEND_AUTH[={@og.value org.opengion.hayabusa.common.SystemData#MAIL_SEND_AUTH}])。
316         * 
317         * @og.rev 5.6.6.0 (2013/07/05)
318         * 
319         * @param  useAuth 認証方式
320         */
321        public void setAuth( final String useAuth ) {
322                auth = nval( useAuth, auth );
323        }
324
325        /**
326         * メール送信認証ユーザをセットします。
327         * 初期値は、システム定数のMAIL_SEND_AUTH_USER を使用します。
328         *
329         * (初期値:システム定数のMAIL_SEND_AUTH_USER[={@og.value org.opengion.hayabusa.common.SystemData#MAIL_SEND_AUTH_USER}])。
330         * 
331         * @og.rev 5.6.6.0 (2013/07/05)
332         * 
333         * @param  user 認証ユーザ
334         */
335        public void setAuthUser( final String user ) {
336                authUser = nval( user, authUser );
337        }
338
339        /**
340         * メール送信認証パスワードをセットします。
341         * 初期値は、システム定数のMAIL_SEND_AUTH_PASSWORD を使用します。
342         *
343         * (初期値:システム定数のMAIL_SEND_AUTH_PASSWORD[={@og.value org.opengion.hayabusa.common.SystemData#MAIL_SEND_AUTH_PASSWORD}])。
344         * 
345         * @og.rev 5.6.6.0 (2013/07/05)
346         * 
347         * @param  pass 認証パスワード
348         */
349        public void setAuthPass( final String pass ) {
350                authPass = nval( pass, authPass );
351        }
352
353        /**
354         * メール送信者アドレスを返します。
355         *
356         * @return      送信者アドレス
357         */
358        public String getFromAddr() {
359                return fromAddr;
360        }
361
362        /**
363         * メールタイトルを返します。
364         *
365         * @return      メールタイトル
366         */
367        public String getTitle() {
368                return mailTitle;
369        }
370
371        /**
372         * メール本文を返します。
373         *
374         * @return      メール本文
375         */
376        public String getContent() {
377                return mailContent;
378        }
379
380        /**
381         * 送信結果を履歴テーブル(GE32)と宛先テーブル(GE34)に登録します。
382         * 登録時に、桁数オーバーにならないように、テーブル定義の桁数を上限として、
383         * 登録前に各項目の桁数整理を行います。
384         *
385         * @og.rev 5.5.5.1 (2012/08/07) リソース系DBID 付け忘れ対策
386         */
387        protected void commitMailDB(){
388                // 履歴テーブルの追加
389                String[] insGE32Args = new String[15];
390                String ykno = getYkno();
391                insGE32Args[GE32_YKNO]          = ykno;
392                insGE32Args[GE32_PARAKEY]       = initParamMap.get( "PARAKEY" );
393                insGE32Args[GE32_PTN_ID]        = trim( initParamMap.get( "PTN_ID" ), 20 );
394                insGE32Args[GE32_FROM_ADDR] = trim( fromAddr, 100);
395                insGE32Args[GE32_TITLE]         = trim( mailTitle, 300);
396                insGE32Args[GE32_CONTENTS]      = trim( mailContent,4000);              // 5.0.3.0 (2009/11/04) CONTENT ⇒ CONTENTS
397                insGE32Args[GE32_ATTACH1]       = "";
398                insGE32Args[GE32_ATTACH2]       = "";
399                insGE32Args[GE32_ATTACH3]       = "";
400                insGE32Args[GE32_ATTACH4]       = "";
401                insGE32Args[GE32_ATTACH5]       = "";
402                if ( attachFiles != null ) {
403                        int attSize = attachFiles.length;
404                        for( int i = 0; i < attSize; i++ ) {
405                                insGE32Args[6 + i] = trim( attachFiles[i], 256);
406                        }
407                }
408                insGE32Args[GE32_DYSET]  = HybsSystem.getDate( "yyyyMMddHHmmss" );
409                insGE32Args[GE32_USRSET] = initParamMap.get( "LOGIN_USERID" );
410                insGE32Args[GE32_PGUPD] = initParamMap.get( "PGID" );
411                insGE32Args[GE32_SYSTEM_ID] = initParamMap.get( "SYSTEM_ID" );
412                DBUtil.dbExecute( insGE32, insGE32Args, appInfo, DBID );        // 5.5.5.1 (2012/08/07)
413
414                // 宛先テーブル追加
415                String[] insGE34Args = new String[10];
416                insGE34Args[GE34_YKNO]= ykno;
417                for( String dstId : mailDstMap.keySet() ) {
418                        insGE34Args[GE34_DST_ID]        = trim( mailDstMap.get( dstId )[MailPattern.IDX_DST_ID]  , 10 );
419                        insGE34Args[GE34_GROUP_ID]      = trim( mailDstMap.get( dstId )[MailPattern.IDX_GROUP_ID], 20 );
420                        insGE34Args[GE34_DST_NAME]      = trim( mailDstMap.get( dstId )[MailPattern.IDX_DST_NAME], 20 );
421                        insGE34Args[GE34_DST_ADDR]      = trim( mailDstMap.get( dstId )[MailPattern.IDX_DST_ADDR], 100 );
422                        insGE34Args[GE34_DST_KBN]       = mailDstMap.get( dstId )[MailPattern.IDX_DST_KBN];
423                        insGE34Args[GE34_FGJ]           = mailDstMap.get( dstId )[MailPattern.IDX_FGJ];
424                        insGE34Args[GE34_DYSET]         = HybsSystem.getDate( "yyyyMMddHHmmss" );
425                        insGE34Args[GE34_USRSET]        = initParamMap.get( "LOGIN_USERID" );
426                        insGE34Args[GE34_PGUPD]         = initParamMap.get( "PGID" );
427                        DBUtil.dbExecute( insGE34, insGE34Args, appInfo, DBID );                // 5.5.5.1 (2012/08/07)
428                }
429        }
430
431        /**
432         * パラメータマップをセットします。
433         *
434         * @param       params  パラメータのマップ
435         */
436        protected void setInitParams( final Map<String, String> params ) {
437                initParamMap = params;
438        }
439
440        /**
441         * 添付ファイル配列をセットします。
442         *
443         * @param       attach1 添付ファイル名1
444         * @param       attach2 添付ファイル名2
445         * @param       attach3 添付ファイル名3
446         * @param       attach4 添付ファイル名4
447         * @param       attach5 添付ファイル名5
448         */
449        protected void setAttachFiles( final String attach1
450                                                                , final String attach2
451                                                                , final String attach3
452                                                                , final String attach4
453                                                                , final String attach5 ) {
454                List<String> fileList = new ArrayList<String>();
455                if( attach1 != null && attach1.length() != 0 ) { fileList.add( attach1 ); }
456                if( attach2 != null && attach2.length() != 0 ) { fileList.add( attach2 ); }
457                if( attach3 != null && attach3.length() != 0 ) { fileList.add( attach3 ); }
458                if( attach4 != null && attach4.length() != 0 ) { fileList.add( attach4 ); }
459                if( attach5 != null && attach5.length() != 0 ) { fileList.add( attach5 ); }
460                attachFiles = fileList.toArray( new String[fileList.size()] );
461        }
462
463        /**
464         * メール宛先マップをセットします。
465         *
466         * @param   mailDst     メール宛先マップ
467         */
468        protected void setMailDstMap( final Map<String, String[]> mailDst ) {
469                mailDstMap = mailDst;
470        }
471
472        /**
473         * メール宛先マップをセットします。
474         *
475         * @return      メール宛先マップ
476         */
477        protected Map<String, String[]> getMailDstMap() {
478                return mailDstMap;
479        }
480
481        /**
482         * 指定の長さ以内の文字列を返します。
483         *
484         * @param       src             オリジナルの文字列
485         * @param       maxLen  指定の長さ
486         *
487         * @return      指定の長さに短縮された文字列
488         */
489        protected String trim( final String src, final int maxLen ) {
490                String rtn = src;
491                if( src != null && src.length() > maxLen ) {
492                        rtn = src.substring( 0, maxLen );
493                }
494                return rtn;
495        }
496
497        /**
498         * アドレスチェックのエラーリストを返します。
499         *
500         * @return      エラーリスト
501         */
502        protected List<String> getErrList(){
503                return errAddrList;
504        }
505
506        /**
507         * 宛先マップを元に、送信オブジェクトに宛先をセットします。
508         * セットする際に、アカウントエラーとなっているアドレスを除外します。
509         * 宛先が存在しない場合、例外を投げます。
510         *
511         * @og.rev 4.3.7.5 (2009/07/08) 送信先名称が設定されていない場合は、アドレスを<>で囲わない
512         *
513         * @param invalidAddr 宛先のリスト
514         */
515        private void setMailDst( final List<String> invalidAddr ){
516                ArrayList<String> toList = new ArrayList<String>();
517                ArrayList<String> ccList = new ArrayList<String>();
518                ArrayList<String> bccList = new ArrayList<String>();
519
520                Map<Integer, ArrayList<String>> tempMap = new HashMap<Integer, ArrayList<String>>();
521                tempMap.put( Integer.valueOf( MailPattern.KBN_TO ),  toList );
522                tempMap.put( Integer.valueOf( MailPattern.KBN_CC ),  ccList );
523                tempMap.put( Integer.valueOf( MailPattern.KBN_BCC ), bccList );
524
525                for( String dstId : mailDstMap.keySet() ) {
526                        String[] dstInfo = mailDstMap.get( dstId );
527                        Integer kbn = Integer.valueOf( dstInfo[MailPattern.IDX_DST_KBN] );
528                        if( !invalidAddr.contains( dstInfo[MailPattern.IDX_DST_ADDR] )
529                                        && !FGJ_ADDR_ERR.equals( dstInfo[MailPattern.IDX_FGJ] )){
530                                dstInfo[MailPattern.IDX_FGJ] = FGJ_SEND_OVER;
531
532                                // 4.3.7.5 (2009/07/08)
533                                String name = dstInfo[MailPattern.IDX_DST_NAME];
534                                if( name != null && name.length() > 0 ) {
535                                        tempMap.get( kbn ).add( dstInfo[MailPattern.IDX_DST_NAME] +  "<"+ dstInfo[MailPattern.IDX_DST_ADDR] + ">" );
536                                }
537                                else {
538                                        tempMap.get( kbn ).add( dstInfo[MailPattern.IDX_DST_ADDR] );
539                                }
540                        }
541                        else {
542                                if( FGJ_SEND_OVER.equals( dstInfo[MailPattern.IDX_FGJ] ) ) {
543                                        dstInfo[MailPattern.IDX_FGJ] = FGJ_ACNT_ERR;
544                                }
545                        }
546                }
547
548                mail.clearTo();         // 宛先(TO)をクリア
549                mail.clearCc();         // 宛先(CC)をクリア
550                mail.clearBcc();        // 宛先(BCC)をクリア
551                boolean haveValidAddr = false ;
552                if( ! toList.isEmpty() ) {      // toのセット
553                        haveValidAddr = true;
554                        String[] to = toList.toArray( new String[toList.size()] );
555                        mail.setTo( to );
556                }
557                if( ! ccList.isEmpty() ) {      // ccのセット
558                        haveValidAddr = true;
559                        String[] cc = ccList.toArray( new String[ccList.size()] );
560                        mail.setCc( cc );
561                }
562                if( ! bccList.isEmpty() ) {     // bccのセット
563                        haveValidAddr = true;
564                        String[] bcc = bccList.toArray( new String[bccList.size()] );
565                        mail.setBcc( bcc );
566                }
567                if( !haveValidAddr ){           // 宛先全部無効の場合、例外を投げます。
568                        String errMsg = "宛先のメールアドレスが有効ではありません。"
569                                                + "TO , CC , BCC のいづれにもアドレスが設定されていません。"; // 5.1.8.0 (2010/07/01) errMsg 修正
570                        throw new RuntimeException( errMsg );
571                }
572        }
573
574        /**
575         * 要求NOを採番します。
576         * この要求NOで履歴テーブル(GE32)と宛先テーブル(GE30)の関連付けを持たせます。
577         *
578         * @og.rev 5.5.5.1 (2012/08/07) リソース系DBID 付け忘れ対策
579         *
580         * @return      要求NO
581         */
582        private String getYkno() {
583                String[][] tmp = DBUtil.dbExecute( selYkno, new String[0], appInfo, DBID );             // 5.5.5.1 (2012/08/07)
584                if( tmp == null || tmp.length == 0 ) {
585                        String errMsg = "要求NO採番エラー"
586                                                + " SQL=" + selYkno ;           // 5.1.8.0 (2010/07/01) errMsg 修正
587                        throw new RuntimeException( errMsg );
588                }
589                return tmp[0][0];
590        }
591
592        /**
593         * メールアドレスのリストよりユーザーIDを逆引きします。
594         *
595         * @param       addressList     メールアドレスのリスト
596         *
597         * @return      ユーザーID
598         */
599        private String getUserIds( final List<String> addressList ){
600                StringBuilder idBuf = new StringBuilder();
601                Map<String,String>  addressMap = new HashMap<String, String>();
602                for( String userId : mailDstMap.keySet() ) {
603                        String[] dstInfo = mailDstMap.get( userId );
604                        addressMap.put( dstInfo[MailPattern.IDX_DST_ADDR], userId );
605                }
606                for(int i=0; i < addressList.size(); i++){
607                        idBuf.append( ',' ).append( addressMap.get( addressList.get( i ) ) );
608                }
609                String rtn = "";
610                if ( idBuf.length() > 0 ) {
611                        rtn = idBuf.toString().substring( 1 );
612                }
613                return rtn;
614        }
615}