OSDN Git Service

Ver8.5.2.0
[opengion/opengionV8.git] / uap / webapps / gf / src / org / opengion / hayabusa / mail / DefaultMailManager.java
1 /*
2  * Copyright (c) 2009 The openGion Project.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13  * either express or implied. See the License for the specific language
14  * governing permissions and limitations under the License.
15  */
16 package org.opengion.hayabusa.mail;
17
18 import org.opengion.fukurou.system.OgRuntimeException ;                         // 6.4.2.0 (2016/01/29)
19 import org.opengion.fukurou.system.DateSet;                                                     // 6.4.2.0 (2016/01/29)
20 import org.opengion.fukurou.util.StringUtil;                                            // 5.9.1.3 (2015/10/30)
21 import org.opengion.fukurou.db.DBUtil;
22 import org.opengion.fukurou.db.ApplicationInfo;
23 import org.opengion.fukurou.mail.MailTX;
24 import static org.opengion.fukurou.util.StringUtil.nval;
25 import static org.opengion.fukurou.system.HybsConst.BUFFER_MIDDLE;      // 6.1.0.0 (2014/12/26) refactoring
26
27 import org.opengion.hayabusa.common.HybsSystem;
28
29 import org.opengion.fukurou.db.ConnectionFactory;                                       // 5.9.26.0 (2017/11/02)
30 import org.opengion.fukurou.db.Transaction;                                                     // 5.9.26.0 (2017/11/02)
31 import org.opengion.fukurou.db.TransactionReal;                                         // 5.9.26.0 (2017/11/02)
32 import org.opengion.fukurou.db.DBFunctionName;                                          // 5.9.26.0 (2017/11/02)
33
34 import java.util.List;
35 import java.util.ArrayList;
36 import java.util.HashMap;
37 import java.util.Map;
38 import java.util.concurrent.ConcurrentMap;                                                      // 6.4.3.3 (2016/03/04)
39 import java.util.stream.Collectors;                                                                     // 6.4.1.1 (2016/01/16)
40
41 import jakarta.mail.Address;
42 import jakarta.mail.SendFailedException;
43 import jakarta.mail.internet.InternetAddress;
44
45 /**
46  * タグ mailSender2 及びバッチによる送信の共通処理部分を実装しています。
47  * 送信タグ mailSender2 もしくは送信デーモンからパラメータを受取ります。
48  * パラメータ中の定型文ID及びシステムIDで定型文マスタよりメールの定型文を取得して、
49  * パラメータ値とマージしてメール文を合成します。同時に、宛先にセットした社員ID、
50  * グループIDと定型文の宛先設定に基づき、社員マスタとグループマスタよりメールアドレス
51  * 情報を取得して送信を行います。
52  * エラーがなければ送信した内容を履歴テーブル、宛先テーブルに書き込みます。
53  * 最後に本処理の呼出元に送信結果、エラーメッセージを返します。
54  *
55  * @og.group メールモジュール
56  *
57  * @version  4.0
58  * @author   Sen.Li
59  * @since    JDK1.6
60  */
61 public class DefaultMailManager {
62 //      // 5.2.0.0 (2010/09/01) Ver4互換モード対応
63 //      // 6.9.5.0 (2018/04/23) VER4_COMPATIBLE_MODE 廃止
64 //      private static final String CONTENTS = HybsSystem.sysBool( "VER4_COMPATIBLE_MODE" ) ? "CONTENT" : "CONTENTS";
65
66         // 5.9.26.0 (2017/11/02) DB共通化のため、DBFunctionNameを使用して、シーケンスを取得するように変更
67
68         // 5.0.3.0 (2009/11/04) CONTENT ⇒ CONTENTS
69         // 5.2.0.0 (2010/09/01) Ver4互換モード対応
70         // 6.4.1.1 (2016/01/16) insGE32 → INS_GE32 , insGE34 → INS_GE34 refactoring
71         // 6.9.5.0 (2018/04/23) VER4_COMPATIBLE_MODE 廃止
72 //      private static final String     INS_GE32                = "INSERT INTO GE32(YKNO,PARA_KEY,PTN_ID,FROM_ADDR,TITLE,"+CONTENTS+",ATTACH1,ATTACH2,ATTACH3,ATTACH4,ATTACH5,DYSET,USRSET,PGUPD,SYSTEM_ID,FGJ)"
73         private static final String     INS_GE32                = "INSERT INTO GE32(YKNO,PARA_KEY,PTN_ID,FROM_ADDR,TITLE,CONTENTS,ATTACH1,ATTACH2,ATTACH3,ATTACH4,ATTACH5,DYSET,USRSET,PGUPD,SYSTEM_ID,FGJ)"
74                                                                                         + " VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,'1')";
75         private static final String INS_GE34            = "INSERT INTO GE34(YKNO,DST_ID,GROUP_ID,DST_NAME,DST_ADDR,DST_KBN,FGJ,DYSET,USRSET,PGUPD)"
76                                                                                         + " VALUES(?,?,?,?,?,?,?,?,?,?)";
77         /** フラグ定数 {@value} */
78         protected static final String FGJ_SEND_WAIT     = "0";
79         /** フラグ定数 {@value} */
80         protected static final String FGJ_SEND_OVER     = "1";
81         /** フラグ定数 {@value} */
82         protected static final String FGJ_ADDR_ERR      = "7";
83         /** フラグ定数 {@value} */
84         protected static final String FGJ_ACNT_ERR      = "8";
85
86         // 内部データのカラム番号(履歴テーブル)
87         private static final int GE32_YKNO              = 0 ;
88         private static final int GE32_PARAKEY   = 1 ;
89         private static final int GE32_PTN_ID    = 2;
90         private static final int GE32_FROM_ADDR = 3;
91         private static final int GE32_TITLE             = 4;
92         private static final int GE32_CONTENTS  = 5;            // 5.0.3.0 (2009/11/04) CONTENT ⇒ CONTENTS
93         private static final int GE32_ATTACH1   = 6;
94         private static final int GE32_ATTACH2   = 7;
95         private static final int GE32_ATTACH3   = 8;
96         private static final int GE32_ATTACH4   = 9;
97         private static final int GE32_ATTACH5   = 10;
98         private static final int GE32_DYSET             = 11;
99         private static final int GE32_USRSET    = 12;
100         private static final int GE32_PGUPD             = 13;
101         private static final int GE32_SYSTEM_ID = 14;
102         // 内部データのカラム番号(履歴テーブル)
103         private static final int GE34_YKNO              = 0 ;
104         private static final int GE34_DST_ID    = 1 ;
105         private static final int GE34_GROUP_ID  = 2 ;
106         private static final int GE34_DST_NAME  = 3 ;
107         private static final int GE34_DST_ADDR  = 4 ;
108         private static final int GE34_DST_KBN   = 5 ;
109         private static final int GE34_FGJ               = 6 ;
110         private static final int GE34_DYSET             = 7 ;
111         private static final int GE34_USRSET    = 8 ;
112         private static final int GE34_PGUPD             = 9 ;
113  //     private static String           host            = HybsSystem.sys( "COMMON_MAIL_SERVER" );
114         private static String           charset         = HybsSystem.sys( "MAIL_DEFAULT_CHARSET" );
115  //     private static String           smtpPort        = HybsSystem.sys( "SMTP_PORT" );                                // 5.4.3.2 (2012/01/06)
116  //     private static String           auth            = HybsSystem.sys( "MAIL_SEND_AUTH" );                   // 5.4.3.2 (2012/01/06)
117  //     private static String           authUser        = HybsSystem.sys( "MAIL_SEND_AUTH_USER" );              // 5.4.3.2 (2012/01/06)
118  //     private static String           authPass        = HybsSystem.sys( "MAIL_SEND_AUTH_PASSWORD" );  // 5.4.3.2 (2012/01/06)
119         private boolean                         debugFlag       ;
120         private final List<String>      errAddrList     = new ArrayList<>();
121         private static final int MAX_RETRY              = 3 ;   // メールアドレスエラー発生した場合、メール再送回数
122
123         // 5.6.6.0 (2013/07/05) host等の外部指定に対応
124         private String          host            = HybsSystem.sys( "COMMON_MAIL_SERVER" );               // 5.6.6.0 (2013/07/05)
125         private String          smtpPort        = HybsSystem.sys( "SMTP_PORT" );                                // 5.6.6.0 (2013/07/05)
126         private String          authType        = HybsSystem.sys( "MAIL_SEND_AUTH" );                   // 6.0.3.0 (2014/11/13) Ver6用キーワード変更
127         private String          authPort        = HybsSystem.sys( "MAIL_SEND_AUTH_PORT" );              // 5.8.1.1 (2014/11/14)
128         private String          authUser        = HybsSystem.sys( "MAIL_SEND_AUTH_USER" );              // 5.6.6.0 (2013/07/05)
129         private String          authPass        = HybsSystem.sys( "MAIL_SEND_AUTH_PASSWORD" );  // 5.6.6.0 (2013/07/05)
130         private boolean         useTLS          = HybsSystem.sysBool( "MAIL_SEND_USE_STARTTLS" );        // 5.9.29.2(2018/02/16) キーワードをVer5 にあわせます。
131
132         private final boolean   useSSL          = HybsSystem.sysBool( "MAIL_SEND_USE_SSL" );    // 6.3.8.0 (2015/09/11)
133
134         private String  mailTitle, mailContent, fromAddr;
135         private String[] attachFiles;
136         /** 6.4.3.1 (2016/02/12) 作成元のMapを、HashMap から ConcurrentHashMap に置き換え。 */
137         private ConcurrentMap<String, String[]> mailDstMap              ;               // 6.4.3.3 (2016/03/04)
138         /** 6.4.3.1 (2016/02/12) 作成元のMapを、HashMap から ConcurrentHashMap に置き換え。 */
139         // 6.4.3.3 (2016/03/04) ConcurrentHashMap を受け取ることを明確にするため、I/FをConcurrentMapに変更します。
140         private ConcurrentMap<String,String>    initParamMap    ;               // パラメータマップ
141         private MailTX                                                  mail                    ;
142
143         /** リソース系DBID */
144         protected final String DBID = HybsSystem.sys( "RESOURCE_DBID" );                // 5.5.5.1 (2012/08/07) リソース系DBID 付け忘れ対応
145
146         /** コネクションにアプリケーション情報を追記するかどうか指定 */
147         private static final boolean USE_DB_APPLICATION_INFO  = HybsSystem.sysBool( "USE_DB_APPLICATION_INFO" ) ;
148
149         /** アプリケーション情報 */
150         // 6.4.1.1 (2016/01/16) DefaultMailManager.appInfo → DefaultMailManager.APP_INFO refactoring
151         protected static final ApplicationInfo APP_INFO;
152         static {
153                 if( USE_DB_APPLICATION_INFO ) {
154                         APP_INFO = new ApplicationInfo();
155                         // ユーザーID,IPアドレス,ホスト名
156                         APP_INFO.setClientInfo( "MailModuel", HybsSystem.HOST_ADRS, HybsSystem.HOST_NAME );
157                         // 画面ID,操作,プログラムID
158                         APP_INFO.setModuleInfo( "MailModuel", "MailManager", "MailManager" );
159                 }
160                 else {
161                         APP_INFO = null;
162                 }
163         }
164
165         /**
166          * デフォルトコンストラクター
167          *
168          * @og.rev 6.4.2.0 (2016/01/29) PMD refactoring. Each class should declare at least one constructor.
169          */
170         public DefaultMailManager() { super(); }                // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。
171
172         /**
173          * 呼出元よりパラメータマップを受取って、メールオブジェクト(mailObj)を作成します。
174          * メールオブジェクトは定型文ID及びシステムIDに基づいて定型文マスタからメールの定型文を取得して、
175          * パラメータ値とマージしてメール文の各項目を合成します。
176          * 宛先については、宛先にセットした社員ID、グループIDと定型文の宛先設定に基づき、社員マスタとグループマスタ
177          * よりメールアドレスを取得して宛先マップを作成します。
178          * まだ、添付ファイルのセット処理も行っています。
179          *
180          * @og.rev 5.6.6.0 (2013/07/05) host等の外部設定対応
181          * @og.rev 6.0.3.0 (2014/11/13) Ver6用キーワード変更
182          * @og.rev 6.4.3.1 (2016/02/12) 作成元のMapを、HashMap から ConcurrentHashMap に置き換え。
183          * @og.rev 6.4.3.3 (2016/03/04) ConcurrentHashMap を受け取ることを明確にするため、I/FをConcurrentMapに変更します。
184          * @og.rev 5.9.15.1 (2016/12/09) エラーリストのクリア
185          * @og.rev 5.9.29.2 (2018/02/16) STARTTLS対応(キーワードをVer5 にあわせます)
186          *
187          * @param       params  パラメータのマップ
188          */
189         public void create( final ConcurrentMap<String, String> params ) {
190                 initParamMap = params;                                                                                  // 6.4.3.1 (2016/02/12)
191                 final MailPattern mailObj = new MailPattern( params );
192                 fromAddr = mailObj.getFromAddr();
193                 setAttachFiles( params.get( "ATTACH1" )
194                                           , params.get( "ATTACH2" )
195                                           , params.get( "ATTACH3" )
196                                           , params.get( "ATTACH4" )
197                                           , params.get( "ATTACH5" ) );                                          // 添付ファイルのセット
198                 mailDstMap      = mailObj.getDstMap();                                                          // 6.4.3.1 (2016/02/12)
199                 mailTitle       = mailObj.getTitle();
200                 mailContent = mailObj.getContent();
201                 errAddrList.clear();                                                                                    // 5.9.15.1 (2016/12/09)
202                 errAddrList.addAll( mailObj.getErrList() );
203
204                 // 5.6.6.0 (2013/07/05)
205                 host            = nval( mailObj.getHost()               ,host           );
206                 smtpPort        = nval( mailObj.getSmtpPort()   ,smtpPort       );
207                 authType        = nval( mailObj.getAuthType()   ,authType       );              // 6.0.3.0 (2014/11/13) Ver6用キーワード変更
208                 authPort        = nval( mailObj.getAuthPort()   ,authPort       );              // 5.8.1.1 (2014/11/14)
209                 authUser        = nval( mailObj.getAuthUser()   ,authUser       );
210                 authPass        = nval( mailObj.getAuthPass()   ,authPass       );
211 //              useTLS          = mailObj.getUseTLS();                  // 5.9.29.2 (2018/02/13)
212                 useTLS          = HybsSystem.sysBool( "MAIL_SEND_USE_STARTTLS" );        // 5.9.29.2(2018/02/16) キーワードをVer5 にあわせます。
213         }
214
215         /**
216          * メール送信を行うメソッドです。
217          * createメソッドより合成した内容で送信を行います。アドレスエラー発生時に、
218          * ユーザー設定(addrCheck)により再送/中止します。
219          * メールサーバーに送信して、例外"SendFailedException"をキャッチできたら、
220          * メールアカウントがエラーとなるのを分かります。そして、例外のオブジェクトから
221          * エラーとなっているアカウントを取得して宛先マップから除外して、残りのアドレスに再送できます。
222          * 送信後履歴テーブル(GE32)、宛先テーブル(GE34)に送信結果を書き込みます。
223          *
224          * @og.rev 5.4.3.2 (2012/01/06) 送信時認証対応
225          * @og.rev 6.0.3.0 (2014/11/13) Ver6用キーワード変更
226          * @og.rev 6.3.8.0 (2015/09/11) SSL接続するかどうかを指定するパラメータを追加します。
227          * @og.rev 5.9.29.2 (2018/02/16) STARTTLS対応(キーワードをVer5 にあわせます)
228          */
229         public void send() {
230                 final List<String> invalidAddrBuf       = new ArrayList<>();
231                 // mail = new MailTX( host, charset );
232 //              mail = new MailTX( host, charset, smtpPort, authType, authPort,authUser, authPass , useSSL );                   // 6.3.8.0 (2015/09/11) SSL接続対応
233                 mail = new MailTX( host, charset, smtpPort, authType, authPort,authUser, authPass, useTLS , useSSL );   // 5.9.29.2 (2019/02/16)
234                 mail.setFrom( fromAddr );                       // 送信者アドレス
235                 mail.setFilename( attachFiles );        // 添付ファイルをセットします。
236                 mail.setSubject( mailTitle );           // メールタイトル
237                 mail.setMessage( mailContent );         // メール本文
238                 mail.setDebug( debugFlag );
239                 setMailDst( invalidAddrBuf );           // 宛先をセットします。
240
241                 // 6.4.1.1 (2016/01/16) PMD refactoring. Avoid instantiating new objects inside loops
242                 // 実際は、エラー処理の中で作成しているだけなので、外に出す必要性は、薄い。
243                 final StringBuilder errMsgBuf = new StringBuilder( BUFFER_MIDDLE );
244
245                 // メール送信を行います。
246                 int retryCount = MAX_RETRY;
247                 while( retryCount > 0 ) {
248                         try {
249                                 mail.sendmail();
250                         }
251                         catch( final RuntimeException rex ) {
252                                 final Throwable cause = rex.getCause();
253                                 if( cause instanceof SendFailedException ) {
254                                         final Address[] invAddress = ( (SendFailedException) cause ).getInvalidAddresses();
255                                         if( invAddress != null ) {
256                                                 final int invCount = invAddress.length;
257                                                 for( int i=0; i<invCount; i++ ) {
258                                                         invalidAddrBuf.add( ( (InternetAddress) invAddress[i] ).getAddress() );
259                                                 }
260                                         }
261                                 }
262                                 else {
263                                         final String errMsg = "送信時にエラー発生しました。" + rex.getMessage();
264                                         throw new OgRuntimeException( errMsg,rex );
265                                 }
266                         }
267
268                         if( invalidAddrBuf.isEmpty() ) {
269                                 retryCount = -1;
270                         }
271                         else {
272                                 // 6.4.1.1 (2016/01/16) PMD refactoring. Avoid instantiating new objects inside loops
273
274                                 errMsgBuf.setLength(0);                         // new StringBuilder の代わり。
275                                 final String errMsg = errMsgBuf.append( "アドレスエラー。ユーザーID:" )
276                                                                                                 .append( getUserIds( invalidAddrBuf ) )
277                                                                                                 .append( " アドレス:" )
278                                                                                                 .append( invalidAddrBuf.stream().collect( Collectors.joining( "," ) ) )
279                                                                                                 .toString();
280
281                                 if( "true".equals( initParamMap.get( "ADDR_CHECK" ) ) ){
282                                         throw new OgRuntimeException( errMsg );
283                                 }
284                                 else {
285                                         // メールアカウントチェックしない場合、無効のメールアドレスを除いて再送します。
286                                         setMailDst( invalidAddrBuf );
287                                         retryCount--;
288                                         invalidAddrBuf.clear();
289                                         errAddrList.add( errMsg );
290                                 }
291                         }
292                 }
293                 commitMailDB();         // 送信結果を履歴テーブル、宛先テーブルにセットします。
294         }
295
296         /**
297          * デバッグ情報の表示を行うかどうか[true/false]をセットします。
298          *
299          * @param   debug  [true:出力する/それ以外:しない]
300          */
301         public void setDebug( final boolean debug ) {
302                 debugFlag = debug;
303         }
304
305         /**
306          * メール送信者アドレスをセットします。
307          *
308          * @param  from 送信者アドレス
309          */
310         public void setFromAddr( final String from ) {
311                 fromAddr = from;
312         }
313
314         /**
315          * メールタイトルをセットします。
316          *
317          * @param  title メールタイトル
318          */
319         public void setTitle( final String title ) {
320                 mailTitle = title;
321         }
322
323         /**
324          * メール本文をセットします。
325          *
326          * @param  content メール本文
327          */
328         public void setContent( final String content ) {
329                 mailContent = content;
330         }
331
332         /**
333          * メール送信ホストをセットします。
334          * 初期値は、システム定数のCOMMON_MAIL_SERVER を使用します。
335          *
336          * (初期値:システム定数のCOMMON_MAIL_SERVER[={@og.value SystemData#COMMON_MAIL_SERVER}])。
337          *
338          * @og.rev 5.6.6.0 (2013/07/05)
339          *
340          * @param  hostName 送信ホスト
341          */
342         public void setHost( final String hostName ) {
343                 host = nval( hostName, host );
344         }
345
346         /**
347          * メール送信ポート番号をセットします。
348          * 初期値は、システム定数のSMTP_PORT を使用します。
349          *
350          * (初期値:システム定数のSMTP_PORT[={@og.value SystemData#SMTP_PORT}])。
351          *
352          * @og.rev 5.6.6.0 (2013/07/05)
353          *
354          * @param  port SMTPポート
355          */
356         public void setPort( final String port ) {
357                 smtpPort = nval( port, smtpPort );
358         }
359
360         /**
361          * メール送信時認証有無をセットします。
362          * 認証を行う場合は「POP_BEFORE_SMTP」と指定して下さい。
363          * 認証時には認証ユーザと認証パスワードを設定する必要があります。
364          * 初期値は、システム定数のMAIL_SEND_AUTH を使用します。
365          *
366          * (初期値:システム定数のMAIL_SEND_AUTH[={@og.value SystemData#MAIL_SEND_AUTH}])。
367          *
368          * @og.rev 6.0.3.0 (2014/11/13) Ver6用キーワード変更
369          *
370          * @param  type 認証方式
371          */
372         public void setAuthType( final String type ) {
373                 authType = nval( type, authType );
374         }
375
376         /**
377          * メール送信認証ユーザをセットします。
378          * 初期値は、システム定数のMAIL_SEND_AUTH_USER を使用します。
379          *
380          * (初期値:システム定数のMAIL_SEND_AUTH_USER[={@og.value SystemData#MAIL_SEND_AUTH_USER}])。
381          *
382          * @og.rev 5.6.6.0 (2013/07/05)
383          *
384          * @param  user 認証ユーザ
385          */
386         public void setAuthUser( final String user ) {
387                 authUser = nval( user, authUser );
388         }
389
390         /**
391          * メール送信認証パスワードをセットします。
392          * 初期値は、システム定数のMAIL_SEND_AUTH_PASSWORD を使用します。
393          *
394          * (初期値:システム定数のMAIL_SEND_AUTH_PASSWORD[={@og.value SystemData#MAIL_SEND_AUTH_PASSWORD}])。
395          *
396          * @og.rev 5.6.6.0 (2013/07/05)
397          *
398          * @param  pass 認証パスワード
399          */
400         public void setAuthPass( final String pass ) {
401                 authPass = nval( pass, authPass );
402         }
403
404         /**
405          * メール送信にSTARTTLSを利用するかのフラグをセットします。
406          * 初期値は、システム定数のMAIL_SEND_USE_STARTTLS を使用します。
407          *
408          * (初期値:システム定数のMAIL_SEND_AUTH_PASSWORD[={@og.value org.opengion.hayabusa.common.SystemData#MAIL_SEND_USE_STARTTLS}])。
409          *
410          * @og.rev 5.9.29.2 (2018/02/16) STARTTLS対応(キーワードをVer5 にあわせます)
411          *
412          * @param  flg TLSの利用有無
413          */
414         public void setUseTLS( final boolean flg ) {
415                 useTLS = flg;
416         }
417
418         /**
419          * メール送信者アドレスを返します。
420          *
421          * @return      送信者アドレス
422          */
423         public String getFromAddr() {
424                 return fromAddr;
425         }
426
427         /**
428          * メールタイトルを返します。
429          *
430          * @return      メールタイトル
431          */
432         public String getTitle() {
433                 return mailTitle;
434         }
435
436         /**
437          * メール本文を返します。
438          *
439          * @return      メール本文
440          */
441         public String getContent() {
442                 return mailContent;
443         }
444
445         /**
446          * 送信結果を履歴テーブル(GE32)と宛先テーブル(GE34)に登録します。
447          * 登録時に、桁数オーバーにならないように、テーブル定義の桁数を上限として、
448          * 登録前に各項目の桁数整理を行います。
449          *
450          * @og.rev 5.5.5.1 (2012/08/07) リソース系DBID 付け忘れ対策
451          * @og.rev 5.9.1.3 (2015/10/30) 4000文字カットをやめる
452          * @og.rev 6.3.9.0 (2015/11/06) Map.keySet() ではなく、Map.values() を使う様に変更。
453          * @og.rev 6.4.2.0 (2016/01/29) DateSet.getDate( String ) を利用するように修正します。
454          */
455         protected void commitMailDB(){
456                 // 履歴テーブルの追加
457                 String[] insGE32Args = new String[15];
458                 final String ykno = getYkno();
459                 insGE32Args[GE32_YKNO]          = ykno;
460                 insGE32Args[GE32_PARAKEY]       = initParamMap.get( "PARAKEY" );
461                 insGE32Args[GE32_PTN_ID]        = trim( initParamMap.get( "PTN_ID" ), 20 );
462                 insGE32Args[GE32_FROM_ADDR] = trim( fromAddr, 100);
463                 insGE32Args[GE32_TITLE]         = trim( mailTitle, 300);
464                 insGE32Args[GE32_CONTENTS]      = mailContent;                                  // 5.9.1.3 (2015/10/30)
465                 insGE32Args[GE32_ATTACH1]       = "";
466                 insGE32Args[GE32_ATTACH2]       = "";
467                 insGE32Args[GE32_ATTACH3]       = "";
468                 insGE32Args[GE32_ATTACH4]       = "";
469                 insGE32Args[GE32_ATTACH5]       = "";
470                 if( attachFiles != null ) {
471                         final int attSize = attachFiles.length;
472                         for( int i=0; i<attSize; i++ ) {
473                                 insGE32Args[6 + i] = trim( attachFiles[i], 256);
474                         }
475                 }
476                 insGE32Args[GE32_DYSET]  = DateSet.getDate( "yyyyMMddHHmmss" );                 // 6.4.2.0 (2016/01/29)
477                 insGE32Args[GE32_USRSET] = initParamMap.get( "LOGIN_USERID" );
478                 insGE32Args[GE32_PGUPD] = initParamMap.get( "PGID" );
479                 insGE32Args[GE32_SYSTEM_ID] = initParamMap.get( "SYSTEM_ID" );
480                 DBUtil.dbExecute( INS_GE32, insGE32Args, APP_INFO, DBID );      // 5.5.5.1 (2012/08/07)
481
482                 // 宛先テーブル追加
483                 String[] insGE34Args = new String[10];
484                 insGE34Args[GE34_YKNO]= ykno;
485
486                 // 6.3.9.0 (2015/11/06) Map.keySet() ではなく、Map.values() を使う様に変更。
487                 for( final String[] dstInfo : mailDstMap.values() ) {
488                         insGE34Args[GE34_DST_ID]        = trim( dstInfo[MailPattern.IDX_DST_ID]  , 10 );
489                         insGE34Args[GE34_GROUP_ID]      = trim( dstInfo[MailPattern.IDX_GROUP_ID], 20 );
490                         insGE34Args[GE34_DST_NAME]      = trim( dstInfo[MailPattern.IDX_DST_NAME], 20 );
491                         insGE34Args[GE34_DST_ADDR]      = trim( dstInfo[MailPattern.IDX_DST_ADDR], 100 );
492                         insGE34Args[GE34_DST_KBN]       = dstInfo[MailPattern.IDX_DST_KBN];
493                         insGE34Args[GE34_FGJ]           = dstInfo[MailPattern.IDX_FGJ];
494                         insGE34Args[GE34_DYSET]         = DateSet.getDate( "yyyyMMddHHmmss" );                  // 6.4.2.0 (2016/01/29)
495                         insGE34Args[GE34_USRSET]        = initParamMap.get( "LOGIN_USERID" );
496                         insGE34Args[GE34_PGUPD]         = initParamMap.get( "PGID" );
497                         DBUtil.dbExecute( INS_GE34, insGE34Args, APP_INFO, DBID );              // 5.5.5.1 (2012/08/07)
498                 }
499         }
500
501         /**
502          * パラメータマップをセットします。
503          *
504          * @og.rev 6.4.3.1 (2016/02/12) 作成元のMapを、HashMap から ConcurrentHashMap に置き換え。
505          * @og.rev 6.4.3.3 (2016/03/04) ConcurrentHashMap を受け取ることを明確にするため、I/FをConcurrentMapに変更します。
506          *
507          * @param       params  パラメータのマップ
508          */
509         protected void setInitParams( final ConcurrentMap<String, String> params ) {
510                 initParamMap = params;
511         }
512
513         /**
514          * 添付ファイル配列をセットします。
515          *
516          * @param       attach1 添付ファイル名1
517          * @param       attach2 添付ファイル名2
518          * @param       attach3 添付ファイル名3
519          * @param       attach4 添付ファイル名4
520          * @param       attach5 添付ファイル名5
521          */
522         protected void setAttachFiles( final String attach1
523                                                                 , final String attach2
524                                                                 , final String attach3
525                                                                 , final String attach4
526                                                                 , final String attach5 ) {
527                 final List<String> fileList = new ArrayList<>();
528                 if( attach1 != null && attach1.length() != 0 ) { fileList.add( attach1 ); }
529                 if( attach2 != null && attach2.length() != 0 ) { fileList.add( attach2 ); }
530                 if( attach3 != null && attach3.length() != 0 ) { fileList.add( attach3 ); }
531                 if( attach4 != null && attach4.length() != 0 ) { fileList.add( attach4 ); }
532                 if( attach5 != null && attach5.length() != 0 ) { fileList.add( attach5 ); }
533                 attachFiles = fileList.toArray( new String[fileList.size()] );
534         }
535
536         /**
537          * メール宛先マップをセットします。
538          *
539          * @og.rev 6.4.3.1 (2016/02/12) 作成元のMapを、HashMap から ConcurrentHashMap に置き換え。
540          * @og.rev 6.4.3.3 (2016/03/04) ConcurrentHashMap を受け取ることを明確にするため、I/FをConcurrentMapに変更します。
541          *
542          * @param   mailDst     メール宛先マップ
543          */
544         protected void setMailDstMap( final ConcurrentMap<String, String[]> mailDst ) {
545                 mailDstMap = mailDst;
546         }
547
548         /**
549          * メール宛先マップをセットします。
550          *
551          * @og.rev 6.4.3.1 (2016/02/12) 作成元のMapを、HashMap から ConcurrentHashMap に置き換え。
552          * @og.rev 6.4.3.1 (2016/02/12) ConcurrentMap 系は、key,val ともに not null 制限です。
553          * @og.rev 6.4.3.3 (2016/03/04) ConcurrentHashMap を受け取ることを明確にするため、I/FをConcurrentMapに変更します。
554          *
555          * @return      メール宛先マップ
556          */
557         protected ConcurrentMap<String, String[]> getMailDstMap() {
558                 return mailDstMap;
559         }
560
561         /**
562          * 指定の長さ以内の文字列を返します。
563          *
564          * @og.rev 5.9.1.3 (2015/10/30) 文字数ではなくByte数に変更
565          *
566          * @param       src             オリジナルの文字列
567          * @param       maxLen  指定の長さ
568          *
569          * @return      指定の長さに短縮された文字列
570          */
571         protected String trim( final String src, final int maxLen ) {
572                 String rtn = src;
573                 if( src != null && src.length() > maxLen ) {
574                         rtn = StringUtil.cut( src, maxLen );            // 5.9.1.3 (2015/10/30)
575                 }
576                 return rtn;
577         }
578
579         /**
580          * アドレスチェックのエラーリストを返します。
581          *
582          * @return      エラーリスト
583          */
584         protected List<String> getErrList(){
585                 return errAddrList;
586         }
587
588         /**
589          * 宛先マップを元に、送信オブジェクトに宛先をセットします。
590          * セットする際に、アカウントエラーとなっているアドレスを除外します。
591          * 宛先が存在しない場合、例外を投げます。
592          *
593          * @og.rev 4.3.7.5 (2009/07/08) 送信先名称が設定されていない場合は、アドレスを<>で囲わない
594          * @og.rev 6.3.9.0 (2015/11/06) Map.keySet() ではなく、Map.values() を使う様に変更。
595          *
596          * @param invalidAddr 宛先のリスト
597          */
598         private void setMailDst( final List<String> invalidAddr ){
599                 final ArrayList<String> toList = new ArrayList<>();
600                 final ArrayList<String> ccList = new ArrayList<>();
601                 final ArrayList<String> bccList = new ArrayList<>();
602
603                 // これ、今見たけど、こんな使い方はどうかと思う。
604                 final Map<Integer, ArrayList<String>> tempMap = new HashMap<>();
605                 tempMap.put( Integer.valueOf( MailPattern.KBN_TO ),  toList );
606                 tempMap.put( Integer.valueOf( MailPattern.KBN_CC ),  ccList );
607                 tempMap.put( Integer.valueOf( MailPattern.KBN_BCC ), bccList );
608
609                 // 6.3.9.0 (2015/11/06) Map.keySet() ではなく、Map.values() を使う様に変更。
610                 for( final String[] dstInfo : mailDstMap.values() ) {
611                         final Integer kbn = Integer.valueOf( dstInfo[MailPattern.IDX_DST_KBN] );
612                         // 6.1.1.0 (2015/01/17) PMD Avoid if(x != y) ..; else ..;
613                         if( invalidAddr.contains( dstInfo[MailPattern.IDX_DST_ADDR] )
614                                         || FGJ_ADDR_ERR.equals( dstInfo[MailPattern.IDX_FGJ] )){
615                                 if( FGJ_SEND_OVER.equals( dstInfo[MailPattern.IDX_FGJ] ) ) {
616                                         dstInfo[MailPattern.IDX_FGJ] = FGJ_ACNT_ERR;
617                                 }
618                         }
619                         else {
620                                 dstInfo[MailPattern.IDX_FGJ] = FGJ_SEND_OVER;
621
622                                 // 4.3.7.5 (2009/07/08)
623                                 final String name = dstInfo[MailPattern.IDX_DST_NAME];
624                                 if( name != null && name.length() > 0 ) {
625                                         tempMap.get( kbn ).add( dstInfo[MailPattern.IDX_DST_NAME] +  "<"+ dstInfo[MailPattern.IDX_DST_ADDR] + ">" );
626                                 }
627                                 else {
628                                         tempMap.get( kbn ).add( dstInfo[MailPattern.IDX_DST_ADDR] );
629                                 }
630                         }
631                 }
632
633                 mail.clearTo();         // 宛先(TO)をクリア
634                 mail.clearCc();         // 宛先(CC)をクリア
635                 mail.clearBcc();        // 宛先(BCC)をクリア
636                 boolean haveValidAddr = false ;
637                 if( ! toList.isEmpty() ) {      // toのセット
638                         haveValidAddr = true;
639                         final String[] to = toList.toArray( new String[toList.size()] );
640                         mail.setTo( to );
641                 }
642                 if( ! ccList.isEmpty() ) {      // ccのセット
643                         haveValidAddr = true;
644                         final String[] cc = ccList.toArray( new String[ccList.size()] );
645                         mail.setCc( cc );
646                 }
647                 if( ! bccList.isEmpty() ) {     // bccのセット
648                         haveValidAddr = true;
649                         final String[] bcc = bccList.toArray( new String[bccList.size()] );
650                         mail.setBcc( bcc );
651                 }
652                 if( !haveValidAddr ){           // 宛先全部無効の場合、例外を投げます。
653                         final String errMsg = "宛先のメールアドレスが有効ではありません。"
654                                                 + "TO , CC , BCC のいづれにもアドレスが設定されていません。"; // 5.1.8.0 (2010/07/01) errMsg 修正
655                         throw new OgRuntimeException( errMsg );
656                 }
657         }
658
659         /**
660          * 要求NOを採番します。
661          * この要求NOで履歴テーブル(GE32)と宛先テーブル(GE30)の関連付けを持たせます。
662          *
663          * @og.rev 5.5.5.1 (2012/08/07) リソース系DBID 付け忘れ対策
664          * @og.rev 5.9.26.0 (2017/11/02) DB共通化対応
665          * @og.rev 7.0.6.4 (2019/11/29) TransactionRealのclose漏れ対応
666          *
667          * @return      要求NO
668          */
669         private String getYkno() {
670 //              // 5.9.26.0 (2017/11/02) DBFnctionNameを利用して、シーケンスを取得
671                 String selYkno = "";
672 //              final Transaction tran = new TransactionReal( APP_INFO );
673 //              try{
674                 try( Transaction tran = new TransactionReal( APP_INFO ) ) {                             // 7.0.6.4 (2019/11/29) try-with-resources文
675                         selYkno = String.valueOf(DBFunctionName.getDBName(ConnectionFactory.getDBName(DBID)).getSequence("GE32S02", tran));
676 //              }finally{
677 //                      tran.close();
678                 }
679                 return selYkno;
680         }
681
682         /**
683          * メールアドレスのリストよりユーザーIDを逆引きします。
684          *
685          * @og.rev 6.1.0.0 (2014/12/26) refactoring : メールアドレスのリスト件数を見てから、処理の実行を決めます。
686          * @og.rev 6.3.9.0 (2015/11/06) Map.keySet() ではなく、Map.entrySet() を使う様に変更。
687          * @og.rev 6.4.3.4 (2016/03/11) forループを、forEach メソッドに置き換えます。
688          *
689          * @param       addressList     メールアドレスのリスト(not null)
690          *
691          * @return      ユーザーID
692          * @og.rtnNotNull
693          */
694         private String getUserIds( final List<String> addressList ){
695                 final int size = addressList.size() ;
696                 if( size == 0 ) { return "" ; }
697
698                 final Map<String,String> addressMap = new HashMap<>();
699                 // 6.3.9.0 (2015/11/06) Map.keySet() ではなく、Map.entrySet() を使う様に変更。
700
701                 // 6.4.3.4 (2016/03/11) forループを、forEach メソッドに置き換えます。
702                 mailDstMap.forEach( (uid,inf) -> addressMap.put( inf[MailPattern.IDX_DST_ADDR], uid ) );
703
704                 final StringBuilder idBuf = new StringBuilder( BUFFER_MIDDLE )
705                         .append( addressMap.get( addressList.get( 0 ) ) );              // 先に size == 0 判定は終わっている。
706                 for( int i=1; i<size; i++ ) {
707                         idBuf.append( ',' ).append( addressMap.get( addressList.get( i ) ) );
708                 }
709                 return idBuf.toString();
710         }
711 }