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 org.opengion.fukurou.system.OgRuntimeException ; // 6.4.2.0 (2016/01/29) 019import static org.opengion.fukurou.system.HybsConst.BUFFER_MIDDLE; // 6.1.0.0 (2014/12/26) refactoring 020import static org.opengion.fukurou.system.HybsConst.CR ; // 6.1.0.0 (2014/12/26) 021import static org.opengion.fukurou.util.StringUtil.csv2ArrayOnly; 022import org.opengion.fukurou.db.DBUtil; 023import org.opengion.hayabusa.common.HybsSystem; 024 025import java.util.ArrayList; 026import java.util.List; 027import java.util.Map; 028import java.util.concurrent.ConcurrentMap; // 6.4.3.3 (2016/03/04) 029import java.util.concurrent.ConcurrentSkipListMap; // 6.4.3.1 (2016/02/12) refactoring 030 031import javax.mail.internet.AddressException; 032import javax.mail.internet.InternetAddress; 033 034/** 035 * メール定型文及びそれも基づいて各項目の合成を行うクラスです。 036 * コンストラクタには定型文ID及びシステムIDで定型文マスタよりメールの定型文を取得します。 037 * メール各項目のゲッターでは、定型文の内容を元にパラメータ値とマージして各項目を合成します。 038 * 宛先について、セットした社員ID、グループIDと定型文の宛先設定に基づき、社員マスタと 039 * グループマスタよりメールアドレス情報を取得して宛先マップを作成します。 040 * 041 * 042 * @og.rev 5.6.6.0 (2013/07/05) host指定対応。GE37必須です。 043 * 044 * @og.group メールモジュール 045 * 046 * @version 4.0 047 * @author Sen.Li 048 * @since JDK1.6 049 */ 050public class MailPattern { 051 052// // 5.2.0.0 (2010/09/01) Ver4互換モード対応 053// // 6.9.5.0 (2018/04/23) VER4_COMPATIBLE_MODE 廃止 054// private static final String CONTENTS = HybsSystem.sysBool( "VER4_COMPATIBLE_MODE" ) ? "CONTENT" : "CONTENTS"; 055// private static final String ADDRESS = HybsSystem.sysBool( "VER4_COMPATIBLE_MODE" ) ? "MEMBER" : "ADDRESS"; 056// private static final String NAME_JA = HybsSystem.sysBool( "VER4_COMPATIBLE_MODE" ) ? "NAME" : "NAME_JA"; 057// private static final String KBNAME = HybsSystem.sysBool( "VER4_COMPATIBLE_MODE" ) ? "NM_KBN" : "KBNAME"; 058 059 // 5.1.0.0 (2009/11/04) CONTENT ⇒ CONTENTS 060 // 5.2.0.0 (2010/09/01) Ver4互換モード対応 061 // 6.4.1.1 (2016/01/16) selGE31 → SEL_GE31 , selGE33 → SEL_GE33 , selGE37 → SEL_GE37 refactoring 062 // 6.9.5.0 (2018/04/23) VER4_COMPATIBLE_MODE 廃止 063// private static final String SEL_GE31 = "SELECT PTN_ID,FROM_ID,TO_ID,CC_ID,BCC_ID,TITLE,"+CONTENTS 064 private static final String SEL_GE31 = "SELECT PTN_ID,FROM_ID,TO_ID,CC_ID,BCC_ID,TITLE,CONTENTS" 065 + " ,JOKEN" // 5.6.6.0 (2013/07/05) 066 + " FROM GE31" 067 + " WHERE SYSTEM_ID =? AND PTN_ID=? AND FGJ='1'"; 068 // 5.1.0.0 (2009/11/04) MEMBER ⇒ ADDRESS , NM_KBN ⇒ KBNAME , NAME ⇒ NAME_JA 069 // 5.2.0.0 (2010/09/01) Ver4互換モード対応 070 // 6.9.5.0 (2018/04/23) VER4_COMPATIBLE_MODE 廃止 071// private static final String SEL_GE33 = "SELECT A."+ADDRESS+",A."+NAME_JA+",B."+NAME_JA 072 private static final String SEL_GE33 = "SELECT A.ADDRESS,A.NAME_JA,B.NAME_JA" 073 + " FROM GE33 A,GE33 B" 074 + " WHERE A.FGJ='1' AND B.FGJ(+)='1' AND A.GROUP_ID=B.GROUP_ID(+)" 075// + " AND A."+KBNAME+"='1' AND B."+KBNAME+"(+)='0' AND A.SYSTEM_ID=B.SYSTEM_ID(+)" 076 + " AND A.KBNAME='1' AND B.KBNAME(+)='0' AND A.SYSTEM_ID=B.SYSTEM_ID(+)" 077 + " AND A.SYSTEM_ID =? " 078 + " AND A.GROUP_ID =?"; 079 080 /** 081 * GE35のメールアドレス検索文 082 * 083 * @og.rev 6.4.1.1 (2016/01/16) selGE35 → SEL_GE35 refactoring 084 */ 085 // 6.9.5.0 (2018/04/23) VER4_COMPATIBLE_MODE 廃止 086// public static final String SEL_GE35 = "SELECT "+NAME_JA+",MAIL" 087 public static final String SEL_GE35 = "SELECT NAME_JA,MAIL" 088 + " FROM GE35" 089 + " WHERE USERID=?"; 090 091 // 5.6.6.0 (2013/07/05) 振り分け条件 092 private static final String SEL_GE37 = "SELECT HOST,PORT,AUTH,AUTHUSER,AUTHPASS" 093 + " FROM GE37" 094 + " WHERE SYSTEM_ID = ?" 095 + " AND JOKEN = ?" 096 + " AND FGJ ='1'"; 097 098 // 内部データのカラム番号(定型文マスタテーブル) 099 // 5.1.9.0 (2010/09/01) public ⇒ private へ変更 100 // private static final int GE31_PTN_ID = 0 ; // 未使用 101 private static final int GE31_FROM_ID = 1 ; 102 private static final int GE31_TO_ID = 2 ; 103 private static final int GE31_CC_ID = 3 ; 104 private static final int GE31_BCC_ID = 4 ; 105 private static final int GE31_TITLE = 5 ; 106 private static final int GE31_CONTENTS = 6 ; // 5.1.0.0 (2009/11/04) CONTENT ⇒ CONTENTS 107 private static final int GE31_JOKEN = 7 ; // 5.6.6.0 (2013/07/05) 108 109 // 内部データのカラム番号(グループマスタ) 110 private static final int GE33_ADDRESS = 0 ; // 5.1.0.0 (2009/11/04) MEMBER ⇒ ADDRESS 111 private static final int GE33_MNAME = 1 ; 112 private static final int GE33_GNAME = 2 ; 113 114 /** 115 * GE35のユーザ名称 116 */ 117 public static final int GE35_NAME = 0 ; 118 /** 119 * GE35のメールアドレス 120 */ 121 public static final int GE35_MAIL = 1 ; 122 123 // 内部データのカラム番号(送信ホストマスタ) 124 private static final int GE37_HOST = 0 ; 125 private static final int GE37_PORT = 1 ; 126 private static final int GE37_AUTH = 2 ; 127 private static final int GE37_AUTHUSER = 3 ; 128 private static final int GE37_AUTHPASS = 4 ; 129 130 // 内部データのカラム番号(宛先テーブル) 131 /** カラム番号(宛先テーブル) {@value} */ 132 public static final int IDX_DST_ID = 0 ; 133 /** カラム番号(宛先テーブル) {@value} */ 134 public static final int IDX_GROUP_ID = 1 ; 135 /** カラム番号(宛先テーブル) {@value} */ 136 public static final int IDX_GROUP_NAME = 2 ; 137 /** カラム番号(宛先テーブル) {@value} */ 138 public static final int IDX_DST_NAME = 3 ; 139 /** カラム番号(宛先テーブル) {@value} */ 140 public static final int IDX_DST_ADDR = 4 ; 141 /** カラム番号(宛先テーブル) {@value} */ 142 public static final int IDX_DST_KBN = 5 ; 143 /** カラム番号(宛先テーブル) {@value} */ 144 public static final int IDX_FGJ = 6 ; 145 146 /** メール送信区分 {@value} */ 147 public static final int KBN_TO = 0 ; // メール送信区分(TO) 148 /** メール送信区分 {@value} */ 149 public static final int KBN_CC = 1 ; // メール送信区分(CC) 150 /** メール送信区分 {@value} */ 151 public static final int KBN_BCC = 2 ; // メール送信区分(BCC) 152 153 private static final String PREFIX_GRP = "GP."; // 6.4.1.1 (2016/01/16) PreFixGroup → PREFIX_GRP refactoring 154 155 private final List<String> errAddrList = new ArrayList<>(); 156 /** 6.4.3.1 (2016/02/12) 作成元のMapを、HashMap から ConcurrentHashMap に置き換え。 */ 157 private final ConcurrentMap<String, String> paramMap ; // 6.4.3.3 (2016/03/04) 158 private String fromId ; 159 private final String toId ; 160 private final String ccId ; 161 private final String bccId ; 162 private String[][] title ; 163 private String[][] content ; 164 165 // 5.6.6.0 (2013/07/05) 166 private String host = HybsSystem.sys( "COMMON_MAIL_SERVER" ); 167 private String smtpPort = HybsSystem.sys( "SMTP_PORT" ); 168 private String authType = HybsSystem.sys( "MAIL_SEND_AUTH" ); // 6.0.3.0 (2014/11/13) Ver6用キーワード変更 169 private String authPort = HybsSystem.sys( "MAIL_SEND_AUTH_PORT" ); // 5.8.1.1 (2014/11/14) 170 private String authUser = HybsSystem.sys( "MAIL_SEND_AUTH_USER" ); 171 private String authPass = HybsSystem.sys( "MAIL_SEND_AUTH_PASSWORD" ); 172// // 5.9.29.2 (2018/02/16) STARTTLS対応(キーワードをVer5 にあわせます) 173// private boolean useTLS = HybsSystem.sysBool( "MAIL_SEND_USE_STARTTLS" ); // 5.9.29.2 (2018/02/16) 174 175 private final String DBID = HybsSystem.sys( "RESOURCE_DBID" ); // 5.5.5.1 (2012/08/07) リソース系DBID 付け忘れ対応 176 177 /** 178 * メール定型文オブジェクトを作成するコンストラクタです。 179 * 定型文マスタより取得したデータを各フィルードにセットします。 180 * 181 * @og.rev 5.5.5.1 (2012/08/07) リソース系DBID 付け忘れ対策 182 * @og.rev 5.6.6.0 (2013/07/05) 振り分け対応 183 * @og.rev 6.0.3.0 (2014/11/13) Ver6用キーワード変更 184 * @og.rev 6.4.1.1 (2016/01/16) DefaultMailManager.appInfo → DefaultMailManager.APP_INFO refactoring 185 * @og.rev 6.4.3.3 (2016/03/04) 戻すMapが、not null制限つきであることを示すため、ConcurrentMap に置き換えます。 186 * 187 * @param params パラメータのマップ 188 */ 189 public MailPattern( final ConcurrentMap<String, String> params ){ 190 paramMap = params; 191 final String sysId = params.get( "SYSTEM_ID" ); 192 final String pid = params.get( "PTN_ID" ); 193 final String[] selGE30Args = { sysId,pid }; 194 final String[][] ptn = DBUtil.dbExecute( SEL_GE31, selGE30Args, DefaultMailManager.APP_INFO, DBID ); // 6.4.1.1 (2016/01/16) 195 if( ptn == null || ptn.length <=0 ) { 196 final String errMsg = "定型文取得できません。システムID:" + sysId + "定型文ID:" + pid + CR 197 + " SQL=" + SEL_GE31 + CR ; 198 throw new OgRuntimeException( errMsg ); 199 } 200 fromId = ptn[0][GE31_FROM_ID]; 201 toId = ptn[0][GE31_TO_ID]; 202 ccId = ptn[0][GE31_CC_ID]; 203 bccId = ptn[0][GE31_BCC_ID]; 204 final String tit = ptn[0][GE31_TITLE]; 205 if( tit != null && tit.length() > 0 ) { 206 title = splitParam( tit ); 207 } 208 final String con = ptn[0][GE31_CONTENTS]; // 5.1.0.0 (2009/11/04) CONTENT ⇒ CONTENTS 209 if( con != null && con.length() > 0 ) { 210 content = splitParam( con ); 211 } 212 // 5.6.6.0 (2013/07/05) 振り分け対応 213 final String joken = ptn[0][GE31_JOKEN]; 214 if( joken != null && joken.length() > 0 ) { 215 final String[] selGE37Args = { sysId,joken }; 216 final String[][] jkn = DBUtil.dbExecute( SEL_GE37, selGE37Args, DefaultMailManager.APP_INFO, DBID ); // 6.4.1.1 (2016/01/16) 217 // 6.0.2.5 (2014/10/31) ptn → jkn の間違い訂正 218 if( jkn == null || jkn.length <=0 ) { 219 final String errMsg = "メールホストの振分先が取得できません。システムID:" + sysId + "振分条件:" + joken + CR 220 + " SQL=" + SEL_GE37 + CR ; 221 throw new OgRuntimeException( errMsg ); 222 } 223 host = jkn[0][GE37_HOST]; 224 smtpPort = jkn[0][GE37_PORT]; 225 authType = jkn[0][GE37_AUTH]; // 6.0.3.0 (2014/11/13) Ver6用キーワード変更 226 authUser = jkn[0][GE37_AUTHUSER]; 227 authPass = jkn[0][GE37_AUTHPASS]; 228 } 229 } 230 231 /** 232 * 定型文の送信者ID欄の設定値とパラメータ{@FROM}を元に送信者アドレスを取得します。 233 * 定型文には{@FROM}とセットされている場合は、パラメータ{@FROM}の値を元に、社員IDをセット 234 * されている場合、直接そのIDを元に社員マスタから送信者アドレスを取得します。 235 * 送信者アドレス取得できなければ例外を投げます。 236 * 237 * @og.rev 4.3.7.5 (2009/07/08) 送信元名称が設定されていない場合は、アドレスを<>で囲わない 238 * 239 * @return 送信者アドレス 240 */ 241 public String getFromAddr(){ 242 // 定型文に{@FROM}⇒ユーザーよりセットしたデータで置換える、ユーザーIDの場合はそのまま 243 if( "{@FROM}".equals( fromId ) ) { 244 fromId = paramMap.get( "FROM" ); 245 } 246 paramMap.put( "FROM_ID" , fromId ); // 送信者ID 247 248 final String[] userInf = getUserInfo( fromId ); 249 String fromAddr = null; 250 if( userInf != null && checkAddr ( fromId, userInf[1] ) ){ // 送信者メールアドレスチェック 251 paramMap.put( "FROM_NAME", userInf[0] ); // 送信者名前 252 // 4.3.7.5 (2009/07/08) 253 if( userInf[0] != null && userInf[0].length() > 0 ) { 254 fromAddr = userInf[0] + "<" + userInf[1] + ">" ; 255 } 256 else { 257 fromAddr = userInf[1]; 258 } 259 paramMap.put( "FROM_ADDR", fromAddr ); // 送信者メールアドレス 260 } 261 else { 262 final String errMsg = "送信者ユーザー情報エラー。ユーザーID:" + fromId; 263 throw new OgRuntimeException( errMsg ); 264 } 265 266 return fromAddr; 267 } 268 269 /** 270 * マージ済のメールタイトルを返します。 271 * 272 * @return メールタイトル 273 * 274 */ 275 public String getTitle(){ 276 return marge( title ); 277 } 278 279 /** 280 * マージ済のメール本文を返します。 281 * 282 * @og.rev 5.1.0.0 (2009/11/04) HEADER ⇒ H_TXT , FOOTER ⇒ F_TXT カラム名変更 283 * 284 * @return メール本文 285 * @og.rtnNotNull 286 */ 287 public String getContent(){ 288 final StringBuilder contentBuf = new StringBuilder( BUFFER_MIDDLE ); 289 final String header = paramMap.get( "HEADER" ); // 5.1.0.0 (2009/11/04) HEADER ⇒ H_TXT 290 if( header != null ) { 291 contentBuf.append( header ).append( '\n' ); 292 } 293 contentBuf.append( marge( content ) ).append( '\n' ); 294 final String fooder = paramMap.get( "FOOTER" ); // 5.1.0.0 (2009/11/04) FOOTER ⇒ F_TXT 295 if( fooder != null ) { 296 contentBuf.append( fooder ); 297 } 298 299 return contentBuf.toString(); 300 } 301 302 /** 303 * 引数の文字列により、定数文字列の部分とパラメータの部分を分解します。 304 * 例:"A{@PARAM1}B"⇒rtn[0][0]="A",rtn[0][1]="B",rtn[1][0]="PARAM1" 305 * 306 * @param src 分解対象の文字列 307 * 308 * @return 定数文字列の部分とパラメータの部分を分解した配列 309 * @og.rtnNotNull 310 */ 311 private String[][] splitParam( final String src ) { 312 if( src == null ) { return new String[2][0]; } 313 314 final ArrayList<String> listCons = new ArrayList<>() ; 315 final ArrayList<String> listPara = new ArrayList<>() ; 316 317 int start = 0; 318 int index = src.indexOf( "{@" ); 319 while( index >= 0 ) { 320 listCons.add( src.substring( start, index ) ); 321 final int end = src.indexOf( '}',index ); 322 if( end < 0 ) { 323 final String errMsg = "{@ と } との対応関係がずれています。" 324 + "src=[" + src + "] : index=" + index ; 325 throw new OgRuntimeException( errMsg ); 326 } 327 listPara.add( src.substring( index + 2, end )); 328 329 start = end+1 ; 330 index = src.indexOf( "{@",start ); 331 } 332 listCons.add ( src.substring( start ) ); 333 334 String[][] rtn = new String[2][]; 335 rtn[0] = listCons.toArray( new String[listCons.size()] ); 336 rtn[1] = listPara.toArray( new String[listPara.size()] ); 337 338 return rtn; 339 } 340 341 /** 342 * 送信先のアドレスをセットします。 343 * 定型文に定義されている宛先(TO、CC、BCC)を引数として渡します。引数には{@TO}、{@CC}、{@BCC}が含まれています。 344 * {@TO}、{@CC}、{@BCC}を初期設定の値で置換えて、実のメールアドレスマップを作成します。 345 * 346 * @og.rev 6.4.3.1 (2016/02/12) 毎回作成しているので、ローカルに移動する。 347 * @og.rev 6.4.3.3 (2016/03/04) 戻すMapが、not null制限つきであることを示すため、ConcurrentMap に置き換えます。 348 * 349 * @return 宛先のマップ 350 */ 351 public ConcurrentMap<String, String[]> getDstMap(){ 352 final String[] toBuf = getDstArray( toId ); 353 final String[] ccBuf = getDstArray( ccId ); 354 final String[] bccBuf = getDstArray( bccId ); 355 356 final ConcurrentMap<String, String[]> mailDstMap = new ConcurrentSkipListMap<>() ; 357 358 // 送信先(TO、CC、BCC)のマップを作成します。 359 setDstAddrMap( mailDstMap , bccBuf, KBN_BCC ); 360 setDstAddrMap( mailDstMap , ccBuf , KBN_CC ); 361 setDstAddrMap( mailDstMap , toBuf , KBN_TO ); 362 363 setDstWord( mailDstMap ); 364 365 return mailDstMap; 366 367 } 368 369 /** 370 * アドレスエラーのメッセージリストを返します。 371 * 372 * @return メッセージリスト 373 */ 374 public List<String> getErrList(){ 375 return errAddrList; 376 } 377 378 /** 379 * 送信先のアドレスをcsv形式から配列にセットします。 380 * 引数は定型文マスタにセットしたものです。例:{@TO},C12345,GP.IT 381 * {@TO}、{@CC}、{@BCC}はパラメータテーブルにセットしたもので置き換えます。 382 * 分解後の配列には、ユーザーID及びグループIDが混在します。 383 * 384 * @param csvId csv形式のアドレス 385 * 386 * @return 送信先のアドレスの配列 387 * @og.rtnNotNull 388 */ 389 private String[] getDstArray( final String csvId ){ 390 final String[] csvArr = csv2ArrayOnly( csvId ); 391 final List<String> list = new ArrayList<>(); 392 393 final int size = csvArr.length; 394 for( int i=0; i<size; i++ ){ 395 if( csvArr[i].startsWith( "{@" )){ 396 final String[] tmp = csv2ArrayOnly( paramMap.get( csvArr[i].substring( 2, csvArr[i].length() - 1 ) ) ); 397 // 6.1.0.0 (2014/12/26) refactoring : Use asList instead of tight loops 398 for( final String dst : tmp ) { list.add( dst ); } 399 } 400 else{ 401 list.add( csvArr[i] ); 402 } 403 } 404 return list.toArray( new String[list.size()] ); 405 } 406 407 /** 408 * 送信先のアドレスマップを作成します。 409 * 410 * ・引数 dstBuf にはユーザーIDとグループID混在する配列です。 411 * ・ユーザーIDの場合、社員マスタのビューから名前及びメールアドレスを取得してマップにセットします。 412 * ・グループIDの場合、グループマスタより、名前及びメールアドレスを取得してマップにセットします。 413 * ・重複のユーザーが存在する場合、最後にセットした方が採用されます。 414 * 415 * @og.rev 5.1.0.0 (2009/11/04) MEMBER ⇒ ADDRESS カラム名変更 416 * @og.rev 6.4.3.1 (2016/02/12) dstMap をローカル変数にして、引数で渡すように変更。 417 * @og.rev 6.4.3.3 (2016/03/04) ConcurrentHashMap を受け取ることを明確にするため、I/FをConcurrentMapに変更します。 418 * 419 * @param dstMap 設定するMapオブジェクト 420 * @param dstBuf ユーザーIDとグループID混在する配列 421 * @param kbn 送信区分[0:TO/1:CC/2:BCC] 422 */ 423 private void setDstAddrMap( final ConcurrentMap<String, String[]> dstMap, final String[] dstBuf, final int kbn ){ 424 // IDX_DST_ID ,IDX_GROUP_ID, IDX_GROUP_NAME ,IDX_DST_NAME ,IDX_DST_ADDR ,IDX_DST_KBN ,IDX_FGJ 425 final String[] dstInit = { "", "", "", "", "", Integer.toString( kbn ), "7" }; 426 427 final int len = dstBuf.length; 428 for( int i=0; i<len; i++ ){ 429 if( dstBuf[i].startsWith( PREFIX_GRP ) ) { // グループIDの場合、グループマスタより、メンバーを取得します。 430 final String[][] groupUsers = getGroupUsers( dstBuf[i].substring( PREFIX_GRP.length() ) ); 431 if( groupUsers.length > 0 ) { 432 final int memberCnt = groupUsers.length; 433 for( int j=0; j<memberCnt; j++ ) { // グループメンバーの処理 434 String[] grpMember = dstInit.clone(); 435 grpMember[IDX_GROUP_ID] = dstBuf[i].substring( PREFIX_GRP.length() ); // グループID 436 grpMember[IDX_GROUP_NAME] = groupUsers[j][GE33_GNAME]; // グループ名 437 grpMember[IDX_DST_ID] = groupUsers[j][GE33_ADDRESS]; // 宛先ID 438 grpMember[IDX_DST_NAME] = groupUsers[j][GE33_MNAME]; // 宛先名 439 if( groupUsers[j][GE33_ADDRESS].contains( "@" ) ) { // メールアドレスがセットされる場合 440 grpMember[IDX_DST_ADDR] = groupUsers[j][GE33_ADDRESS]; // メールアドレス 441 } 442 else { // 社員IDがセットされた場合 443 final String[] userAddr = getUserInfo( groupUsers[j][GE33_ADDRESS] ); 444 if( userAddr != null && userAddr.length > 0 ){ 445 grpMember[IDX_DST_ADDR] = userAddr[GE35_MAIL]; // メールアドレス 446 } 447 } 448 if( checkAddr( grpMember[IDX_DST_ID], grpMember[IDX_DST_ADDR] ) ){ // アドレス構文チェック 449 grpMember[IDX_FGJ] = DefaultMailManager.FGJ_SEND_WAIT; // 送信待 450 } 451 else { 452 grpMember[IDX_FGJ] = DefaultMailManager.FGJ_ADDR_ERR; // アドレス取得エラー 453 errAddrList.add( "アドレス取得エラー。ユーザーID:" + grpMember[IDX_DST_ID] + " アドレス:" + grpMember[IDX_DST_ADDR] ); 454 } 455 dstMap.put( groupUsers[j][GE33_ADDRESS], grpMember ); 456 } 457 } 458 else { // グループマスタよりメンバー取得できない場合 459 String[] emptyGp = dstInit.clone(); 460 emptyGp[IDX_GROUP_ID] = dstBuf[i]; // グループID 461 emptyGp[IDX_GROUP_NAME] = "*"; // グループID 462 emptyGp[IDX_DST_ID] = "NO-MEMBER"; // 宛先ID 463 dstMap.put( dstBuf[i], emptyGp ); 464 } 465 } 466 else { // ユーザーIDの場合 467 String[] indMember = dstInit.clone(); 468 indMember[IDX_DST_ID] = dstBuf[i]; // 宛先ID 469 indMember[IDX_GROUP_ID] = "*"; // グループID 470 indMember[IDX_GROUP_NAME] = "*"; // グループID 471 final String[] userAddr = getUserInfo( dstBuf[i] ); 472 if( userAddr != null && userAddr.length > 0 ){ 473 indMember[IDX_DST_NAME] = userAddr[GE35_NAME]; // 宛先名 474 indMember[IDX_DST_ADDR] = userAddr[GE35_MAIL]; // メールアドレス 475 if( checkAddr( indMember[IDX_DST_ID], userAddr[1] ) ) { 476 indMember[IDX_FGJ] = DefaultMailManager.FGJ_SEND_WAIT; 477 } 478 else { 479 indMember[IDX_FGJ] = DefaultMailManager.FGJ_ADDR_ERR; 480 errAddrList.add( "アドレス取得エラー。ユーザーID:" + indMember[IDX_DST_ID] + " アドレス:" + indMember[IDX_DST_ADDR] ); 481 } 482 483 } 484 else { 485 indMember[IDX_FGJ] = DefaultMailManager.FGJ_ADDR_ERR; // 状況コード 486 } 487 dstMap.put( dstBuf[i], indMember ); 488 } 489 } 490 } 491 492 /** 493 * グループマスタより、ユーザー情報を取得します。 494 * 戻り値の配列には、ユーザーIDまたはメールアドレス、ユーザー名、グループ名が格納されています。 495 * 496 * @og.rev 5.5.5.1 (2012/08/07) リソース系DBID 付け忘れ対策 497 * @og.rev 6.4.1.1 (2016/01/16) DefaultMailManager.appInfo → DefaultMailManager.APP_INFO refactoring 498 * 499 * @param groupId グループID 500 * 501 * @return ユーザー情報 502 */ 503 private String[][] getGroupUsers( final String groupId ){ 504 final String sysId = paramMap.get( "SYSTEM_ID" ); 505 final String[] ge33SelArgs = { sysId,groupId }; 506 final String[][] ge33Datas = DBUtil.dbExecute( SEL_GE33,ge33SelArgs,DefaultMailManager.APP_INFO, DBID ); // 6.4.1.1 (2016/01/16) 507 508 if( ge33Datas.length == 0 ) { 509 final String errMsg = "グループ情報取得できません。グループID:" + groupId ; 510 if( "true".equals( paramMap.get( "ADDR_CHECK" ) ) ){ 511 throw new OgRuntimeException( errMsg ); 512 } 513 else { 514 errAddrList.add( errMsg ); 515 } 516 } 517 return ge33Datas; 518 } 519 520 /** 521 * メール送信ホストを返します。 522 * GE31のJOKEN(振り分け条件)を元に、GE37テーブルの HOST を取得します。 523 * 振り分け条件が未設定の場合は、システム定数のCOMMON_MAIL_SERVER を使用します。 524 * 525 * (初期値:システム定数のCOMMON_MAIL_SERVER[={@og.value SystemData#COMMON_MAIL_SERVER}])。 526 * 527 * @og.rev 5.6.6.0 (2013/07/05) 528 * 529 * @return メール送信ホスト 530 */ 531 public String getHost(){ 532 return host; 533 } 534 535 /** 536 * メール送信ポート番号を返します 537 * GE31のJOKEN(振り分け条件)を元に、GE37テーブルの PORT を取得します。 538 * 振り分け条件が未設定の場合は、システム定数のSMTP_PORT を使用します。 539 * 540 * (初期値:システム定数のSMTP_PORT[={@og.value SystemData#SMTP_PORT}])。 541 * 542 * @og.rev 5.6.6.0 (2013/07/05) 543 * 544 * @return メール送信ポート番号 545 */ 546 public String getSmtpPort(){ 547 return smtpPort; 548 } 549 550 /** 551 * メール送信時認証有無を返します 552 * GE31のJOKEN(振り分け条件)を元に、GE37テーブルの AUTH を取得します。 553 * 振り分け条件が未設定の場合は、システム定数のMAIL_SEND_AUTH を使用します。 554 * 555 * (初期値:システム定数のMAIL_SEND_AUTH[={@og.value SystemData#MAIL_SEND_AUTH}])。 556 * 557 * @og.rev 6.0.3.0 (2014/11/13) Ver6用キーワード変更 558 * 559 * @return メール送信時認証有無 560 */ 561 public String getAuthType(){ 562 return authType; 563 } 564 565 /** 566 * メール送信認証ポートを返します。 567 * 「POP_BEFORE_SMTP」認証を行う場合に、POPサーバーに接続するポート番号を返します。 568 * GE37テーブルに指定するカラムはありません。 569 * 初期値は、システム定数のMAIL_SEND_AUTH_PORT を使用します。 570 * 571 * (初期値:システム定数のMAIL_SEND_AUTH_PORT[={@og.value SystemData#MAIL_SEND_AUTH_PORT}])。 572 * 573 * @og.rev 5.8.1.1 (2014/11/14) メール送信時認証「POP_BEFORE_SMTP」追加 574 * 575 * @return メール送信認証ポート 576 */ 577 public String getAuthPort(){ 578 return authPort; 579 } 580 581 /** 582 * メール送信認証ユーザを返します 583 * GE31のJOKEN(振り分け条件)を元に、GE37テーブルの AUTHUSER を取得します。 584 * 振り分け条件が未設定の場合は、システム定数のMAIL_SEND_AUTH_USER を使用します。 585 * 586 * (初期値:システム定数のMAIL_SEND_AUTH_USER[={@og.value SystemData#MAIL_SEND_AUTH_USER}])。 587 * 588 * @og.rev 5.6.6.0 (2013/07/05) 589 * 590 * @return メール送信認証ユーザ 591 */ 592 public String getAuthUser(){ 593 return authUser; 594 } 595 596 /** 597 * メール送信認証パスワードを返します 598 * GE31のJOKEN(振り分け条件)を元に、GE37テーブルの AUTHPASS を取得します。 599 * 振り分け条件が未設定の場合は、システム定数のMAIL_SEND_AUTH_PASSWORD を使用します。 600 * 601 * (初期値:システム定数のMAIL_SEND_AUTH_PASSWORD[={@og.value SystemData#MAIL_SEND_AUTH_PASSWORD}])。 602 * 603 * @og.rev 5.6.6.0 (2013/07/05) 604 * 605 * @return メール送信認証パスワード 606 */ 607 public String getAuthPass(){ 608 return authPass; 609 } 610 611// /** 612// * メール送信時にSTARTTLSの暗号化を行うかを指定します。 613// * 現在はシステム定数のMAIL_SEND_USE_STARTTLSをそのまま使用します。 614// * 615// * (初期値:システム定数のMAIL_SEND_AUTH_PASSWORD[={@og.value org.opengion.hayabusa.common.SystemData#MAIL_SEND_USE_STARTTLS}])。 616// * 617// * @og.rev 5.9.29.2 (2018/02/16) STARTTLS対応(キーワードをVer5 にあわせます) 618// * 619// * @return メール送信時TLS利用有無 620// */ 621// public boolean getUseTLS(){ 622// return useTLS; 623// } 624 625 /** 626 * アドレスの構文チェックを行います、合法の場合は'true'(取得できた)、違法の場合は'false'(有効アドレス取得できず)を返します。 627 * 628 * @param userId ユーザーID 629 * @param address アドレス 630 * 631 * @return アドレスの構文チェック結果(true:取得/false:取得できず) 632 */ 633 private boolean checkAddr( final String userId, final String address ) { 634 boolean rtn = true; 635 try { 636 new InternetAddress( address ); 637 } 638 catch( final AddressException aep ) { 639 if( "true".equals( paramMap.get( "ADDR_CHECK" ) ) ) { 640 final String errMsg = "ユーザーメールアドレスエラー。ユーザーID:" + userId + " アドレス:" + address; 641 throw new OgRuntimeException( errMsg,aep ); 642 } 643 rtn = false; 644 } 645 return rtn; 646 } 647 648 /** 649 * 引数の配列から文書を合成します。 650 * src[0]に配列には定数文字列、src[1]にはパラメータ 651 * 652 * @param src 引数の配列 653 * 654 * @return 合成された文章 655 * @og.rtnNotNull 656 */ 657 private String marge( final String[][] src ){ 658 final StringBuilder rtnBuf = new StringBuilder( BUFFER_MIDDLE ); 659 if( src != null ) { 660 final int len = src[1].length; 661 for( int i=0; i< len; i++ ) { 662 rtnBuf.append( src[0][i] ); 663 rtnBuf.append( paramMap.get( src[1][i] ) ); 664 } 665 rtnBuf.append( src[0][len] ); 666 } 667 return rtnBuf.toString(); // 6.1.0.0 (2014/12/26) refactoring 668 } 669 670 /** 671 * 宛先(TO、CC、BCC)のID、名前、メールアドレスをパラメータマップにセットします。 672 * 673 * @param mailDstMap メールあて先マップ 674 * 675 * @og.rev 6.3.9.0 (2015/11/06) Map.keySet() ではなく、Map.entrySet() を使う様に変更。 676 * @og.rev 6.4.3.1 (2016/02/12) dstMap をローカル変数にして、引数で渡すように変更。 677 * @og.rev 6.4.3.3 (2016/03/04) ConcurrentHashMap を受け取ることを明確にするため、I/FをConcurrentMapに変更します。 678 */ 679 private void setDstWord( final ConcurrentMap<String, String[]> mailDstMap ) { 680 final StringBuilder to_id = new StringBuilder( BUFFER_MIDDLE ); 681 final StringBuilder to_name = new StringBuilder( BUFFER_MIDDLE ); 682 final StringBuilder to_addr = new StringBuilder( BUFFER_MIDDLE ); 683 final StringBuilder cc_id = new StringBuilder( BUFFER_MIDDLE ); 684 final StringBuilder cc_name = new StringBuilder( BUFFER_MIDDLE ); 685 final StringBuilder cc_addr = new StringBuilder( BUFFER_MIDDLE ); 686 final StringBuilder bcc_id = new StringBuilder( BUFFER_MIDDLE ); 687 final StringBuilder bcc_name = new StringBuilder( BUFFER_MIDDLE ); 688 final StringBuilder bcc_addr = new StringBuilder( BUFFER_MIDDLE ); 689 int kbn; 690 // 6.3.9.0 (2015/11/06) Map.keySet() ではなく、Map.entrySet() を使う様に変更。 691 for( final Map.Entry<String,String[]> entry : mailDstMap.entrySet() ) { 692 final String dstId = entry.getKey(); 693 final String[] dstInfo = entry.getValue(); 694 695 kbn = Integer.parseInt( dstInfo[IDX_DST_KBN]); 696 switch( kbn ) { 697 case KBN_TO: 698 to_id.append( ',' ).append( dstId ); 699 to_name.append( ',' ).append( dstInfo[IDX_DST_NAME] ); 700 to_addr.append( ',' ).append( dstInfo[IDX_DST_NAME] ) 701 .append( '<' ).append( dstInfo[IDX_DST_ADDR] ).append( '>' ); // 6.0.2.5 (2014/10/31) char を append する。 702 break; 703 case KBN_CC: 704 cc_id.append( ',' ).append( dstId ); 705 cc_name.append( ',' ).append( dstInfo[IDX_DST_NAME] ); 706 cc_addr.append( ',' ).append( dstInfo[IDX_DST_NAME] ) 707 .append( '<' ).append( dstInfo[IDX_DST_ADDR] ).append( '>' ); // 6.0.2.5 (2014/10/31) char を append する。 708 break; 709 case KBN_BCC: 710 bcc_id.append( ',' ).append( dstId ); 711 bcc_name.append( ',' ).append( dstInfo[IDX_DST_NAME] ); 712 bcc_addr.append( ',' ).append( dstInfo[IDX_DST_NAME] ) 713 .append( '<' ).append( dstInfo[IDX_DST_ADDR] ).append( '>' ); // 6.0.2.5 (2014/10/31) char を append する。 714 break; 715 default: 716 final String errMsg = "このアドレス区分がサポートされません。区分:" + kbn; 717 throw new OgRuntimeException( errMsg ); 718 } 719 } 720 721 // 6.4.3.1 (2016/02/12) String#toString().substring( 1 ) でなく、StringBuilder#substring( 1 ) で、String が返されます。 722 // 予約語マップに追加します。 723 paramMap.put( "TO_ID" , to_id .length() > 0 ? to_id .substring( 1 ) : "" ); 724 paramMap.put( "TO_NAME" , to_name .length() > 0 ? to_name .substring( 1 ) : "" ); 725 paramMap.put( "TO_ADDR" , to_addr .length() > 0 ? to_addr .substring( 1 ) : "" ); 726 paramMap.put( "CC_ID" , cc_id .length() > 0 ? cc_id .substring( 1 ) : "" ); 727 paramMap.put( "CC_NAME" , cc_name .length() > 0 ? cc_name .substring( 1 ) : "" ); 728 paramMap.put( "CC_ADDR" , cc_addr .length() > 0 ? cc_addr .substring( 1 ) : "" ); 729 paramMap.put( "BCC_ID" , bcc_id .length() > 0 ? bcc_id .substring( 1 ) : "" ); 730 paramMap.put( "BCC_NAME", bcc_name .length() > 0 ? bcc_name.substring( 1 ) : "" ); 731 paramMap.put( "BCC_ADDR", bcc_addr .length() > 0 ? bcc_addr.substring( 1 ) : "" ); 732 733 } 734 735 /** 736 * 社員マスタより名前、メールアドレスを取得します。 737 * 戻り値 rtn[0]:ユーザー名、 rtn[1]:ユーザーメールアドレス 738 * 739 * @og.rev 4.3.6.6 (2009/05/15) メールアドレスが直接指定された場合に対応 740 * @og.rev 5.5.5.1 (2012/08/07) リソース系DBID 付け忘れ対策 741 * @og.rev 6.4.1.1 (2016/01/16) DefaultMailManager.appInfo → DefaultMailManager.APP_INFO refactoring 742 * 743 * @param userId ユーザーID 744 * 745 * @return 配列文字列(rtn[0]:ユーザー名、 rtn[1]:ユーザーメールアドレス) 746 */ 747 private String[] getUserInfo( final String userId ){ 748 String[] rtn = null; 749 750 if( userId.contains( "@" ) ) { 751 rtn = new String[2]; 752 rtn[0] = ""; 753 rtn[1] = userId; 754 } 755 else { 756 final String[] ge35SelArgs = { userId }; 757 final String[][] ge35Datas = DBUtil.dbExecute( SEL_GE35,ge35SelArgs,DefaultMailManager.APP_INFO, DBID ); // 6.4.1.1 (2016/01/16) 758 if( ge35Datas.length > 0 ) { 759 rtn = ge35Datas[0]; 760 } 761 else { 762 final String errMsg = "ユーザー情報取得できません。ユーザーID:" + userId ; 763 if( "true".equals( paramMap.get( "ADDR_CHECK" ) ) ){ 764 throw new OgRuntimeException( errMsg ); 765 } 766 else { 767 errAddrList.add( errMsg ); 768 } 769 } 770 } 771 return rtn; 772 } 773}