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 java.util.concurrent.ConcurrentMap; // 6.4.3.3 (2016/03/04) 020import java.util.concurrent.ConcurrentHashMap; // 6.4.3.1 (2016/02/12) refactoring 021import java.util.concurrent.ConcurrentSkipListMap; // 6.4.3.1 (2016/02/12) refactoring 022 023import org.opengion.fukurou.system.DateSet; // 6.4.2.0 (2016/01/29) 024import org.opengion.fukurou.db.DBUtil; 025import org.opengion.fukurou.db.ApplicationInfo; 026import org.opengion.fukurou.db.Transaction; // 5.9.31.1 (2018/04/13) 027import org.opengion.fukurou.db.TransactionReal; // 5.9.31.1 (2018/04/13) 028import org.opengion.fukurou.db.ConnectionFactory; // 5.9.31.1 (2018/04/13) 029import org.opengion.fukurou.db.DBFunctionName; // 5.9.31.1 (2018/04/13) 030import org.opengion.fukurou.util.StringUtil; 031import org.opengion.hayabusa.common.HybsSystem; 032 033import static org.opengion.fukurou.util.StringUtil.nval; // 6.4.3.3 (2016/03/04) 034 035/** 036 * メールモジュール関係の機能の一部を他から使用するためのクラスです。 037 * 038 * ※MailSenderTagからGE32,34へ履歴を出力する機能を追加する際に、モジュール系の動作を本パッケージに集約しておくために作成。 039 * 必要としている箇所のみ実装。 040 * 041 * @og.rev 5.9.2.3 (2015/11/27) 新規作成 042 * 043 * @og.group メールモジュール 044 * 045 * @version 4.0 046 * @author Takahashi Masakazu 047 * @since JDK1.6 048 */ 049public class MailModuleUtil { 050 051// // Ver4互換モード対応 052// // 6.9.5.0 (2018/04/23) VER4_COMPATIBLE_MODE 廃止 053// private static final String CONTENTS = HybsSystem.sysBool( "VER4_COMPATIBLE_MODE" ) ? "CONTENT" : "CONTENTS"; 054 055// // 6.4.1.1 (2016/01/16) selYkno → SEL_YKNO , insGE32 → INS_GE32 , insGE34 → INS_GE34 refactoring 056// private static final String SEL_YKNO = "SELECT GE32S02.NEXTVAL YKNO FROM DUAL"; 057 058 private static final String SEL_YKNO = "GE32S02"; // 5.9.31.1 (2018/04/13) 059 // 6.9.5.0 (2018/04/23) VER4_COMPATIBLE_MODE 廃止 060// 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)" 061 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)" 062 + " VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,'1')"; 063 private static final String INS_GE34 = "INSERT INTO GE34(YKNO,DST_ID,GROUP_ID,DST_NAME,DST_ADDR,DST_KBN,FGJ,DYSET,USRSET,PGUPD)" 064 + " VALUES(?,?,?,?,?,?,?,?,?,?)"; 065 066 // 内部データのカラム番号(履歴テーブル) 067 private static final int GE32_YKNO = 0 ; 068 private static final int GE32_PARAKEY = 1 ; 069 private static final int GE32_PTN_ID = 2; 070 private static final int GE32_FROM_ADDR = 3; 071 private static final int GE32_TITLE = 4; 072 private static final int GE32_CONTENTS = 5; 073 // private static final int GE32_ATTACH1 = 6; 074 // private static final int GE32_ATTACH2 = 7; 075 // private static final int GE32_ATTACH3 = 8; 076 // private static final int GE32_ATTACH4 = 9; 077 // private static final int GE32_ATTACH5 = 10; 078 private static final int GE32_DYSET = 11; 079 private static final int GE32_USRSET = 12; 080 private static final int GE32_PGUPD = 13; 081 private static final int GE32_SYSTEM_ID = 14; 082 // 内部データのカラム番号(履歴テーブル) 083 private static final int GE34_YKNO = 0 ; 084 private static final int GE34_DST_ID = 1 ; 085 private static final int GE34_GROUP_ID = 2 ; 086 private static final int GE34_DST_NAME = 3 ; 087 private static final int GE34_DST_ADDR = 4 ; 088 private static final int GE34_DST_KBN = 5 ; 089 private static final int GE34_FGJ = 6 ; 090 private static final int GE34_DYSET = 7 ; 091 private static final int GE34_USRSET = 8 ; 092 private static final int GE34_PGUPD = 9 ; 093 094 // アドレスマップ 095 private static final int IDX_DST_ADDR = 0; 096 private static final int IDX_DST_KBN = 1; 097 098 /** メール送信区分 {@value} */ 099 private static final int KBN_TO = 0 ; // メール送信区分(TO) 100 /** メール送信区分 {@value} */ 101 private static final int KBN_CC = 1 ; // メール送信区分(CC) 102 /** メール送信区分 {@value} */ 103 private static final int KBN_BCC = 2 ; // メール送信区分(BCC) 104 105 /** 6.4.3.1 (2016/02/12) PMD refactoring. TreeMap → ConcurrentSkipListMap に置き換え。 */ 106 private final ConcurrentMap<String, String[]> mailDstMap = new ConcurrentSkipListMap<>() ; // 6.4.3.3 (2016/03/04) 107 108 /** 6.4.3.1 (2016/02/12) PMD refactoring. HashMap → ConcurrentHashMap に置き換え。 */ 109 private final ConcurrentMap<String, String> initParamMap = new ConcurrentHashMap<>(); // パラメータマップ 110 111 protected final String DBID = HybsSystem.sys( "RESOURCE_DBID" ); // 5.5.5.1 (2012/08/07) リソース系DBID 付け忘れ対応 112 protected final DBFunctionName dbName = DBFunctionName.getDBName( ConnectionFactory.getDBName( DBID ) ); // 5.9.31.1 (2018/04/13) 113 114 /** コネクションにアプリケーション情報を追記するかどうか指定 */ 115 private static final boolean USE_DB_APPLICATION_INFO = HybsSystem.sysBool( "USE_DB_APPLICATION_INFO" ) ; 116 117 /** アプリケーション情報 */ 118 private static final ApplicationInfo APP_INFO; // 6.4.1.1 (2016/01/16) appInfo → APP_INFO refactoring 119 120 static { 121 if( USE_DB_APPLICATION_INFO ) { 122 APP_INFO = new ApplicationInfo(); 123 // ユーザーID,IPアドレス,ホスト名 124 APP_INFO.setClientInfo( "MailModuel", HybsSystem.HOST_ADRS, HybsSystem.HOST_NAME ); 125 // 画面ID,操作,プログラムID 126 APP_INFO.setModuleInfo( "MailModuel", "MailManager", "MailManager" ); 127 } 128 else { 129 APP_INFO = null; 130 } 131 } 132 133 /** 134 * デフォルトコンストラクター 135 * 136 * @og.rev 6.4.2.0 (2016/01/29) PMD refactoring. Each class should declare at least one constructor. 137 */ 138 public MailModuleUtil() { super(); } // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。 139 140 /** 141 * 履歴テーブル(GE32)と宛先テーブル(GE34)に登録します。 142 * 登録時に、桁数オーバーにならないように、テーブル定義の桁数を上限として、 143 * 登録前に各項目の桁数整理を行います。 144 * 145 * @og.rev 5.9.3.0 (2015/12/04) 添付ファイル対応 146 * @og.rev 6.4.2.0 (2016/01/29) DateSet.getDate( String ) を利用するように修正します。 147 * @og.rev 6.4.3.2 (2016/02/19) Map を、 keySet() ではなく、values() に変更します。 148 * 149 */ 150 public void commitMailDB(){ 151 // 履歴テーブルの追加 152 String[] insGE32Args = new String[15]; 153 final String ykno = getYkno(); 154 final String[] attachFiles = StringUtil.csv2Array( initParamMap.get( "FILES" ) ); // 5.9.3.0 155 156 insGE32Args[GE32_YKNO] = ykno; 157 insGE32Args[GE32_PARAKEY] = initParamMap.get( "PARAKEY" ); 158 insGE32Args[GE32_PTN_ID] = trim( initParamMap.get( "PTN_ID" ), 20 ); 159 insGE32Args[GE32_FROM_ADDR] = trim( initParamMap.get( "FROM" ), 100); 160 insGE32Args[GE32_TITLE] = trim( initParamMap.get( "TITLE" ), 300); 161 insGE32Args[GE32_CONTENTS] = initParamMap.get( "CONTENT" ); 162 // insGE32Args[GE32_ATTACH1] = ""; 163 // insGE32Args[GE32_ATTACH2] = ""; 164 // insGE32Args[GE32_ATTACH3] = ""; 165 // insGE32Args[GE32_ATTACH4] = ""; 166 // insGE32Args[GE32_ATTACH5] = ""; 167 // 5.9.3.0 168 if( attachFiles != null ) { 169 final int attSize = attachFiles.length; 170 for( int i = 0; i < attSize; i++ ) { 171 insGE32Args[6 + i] = trim( attachFiles[i], 256); 172 } 173 } 174 175 insGE32Args[GE32_DYSET] = DateSet.getDate( "yyyyMMddHHmmss" ); // 6.4.2.0 (2016/01/29) 176 insGE32Args[GE32_USRSET] = initParamMap.get( "LOGIN_USERID" ); 177 insGE32Args[GE32_PGUPD] = initParamMap.get( "PGID" ); 178 insGE32Args[GE32_SYSTEM_ID] = initParamMap.get( "SYSTEM_ID" ); 179 DBUtil.dbExecute( INS_GE32, insGE32Args, APP_INFO, DBID ); // 5.5.5.1 (2012/08/07) 180 181 // 宛先テーブル追加 182 String[] insGE34Args = new String[10]; 183 insGE34Args[GE34_YKNO]= ykno; 184 // 6.4.3.2 (2016/02/19) Map を、 keySet() ではなく、values() に変更します。 185 for( final String[] vals : mailDstMap.values() ) { 186 insGE34Args[GE34_DST_ID] = trim( vals[IDX_DST_ADDR], 10 ); 187 insGE34Args[GE34_GROUP_ID] = ""; 188 insGE34Args[GE34_DST_NAME] = ""; 189 insGE34Args[GE34_DST_ADDR] = trim( vals[IDX_DST_ADDR], 100 ); 190 insGE34Args[GE34_DST_KBN] = vals[IDX_DST_KBN]; 191 insGE34Args[GE34_FGJ] = "1"; 192 insGE34Args[GE34_DYSET] = DateSet.getDate( "yyyyMMddHHmmss" ); // 6.4.2.0 (2016/01/29) 193 insGE34Args[GE34_USRSET] = initParamMap.get( "LOGIN_USERID" ); 194 insGE34Args[GE34_PGUPD] = initParamMap.get( "PGID" ); 195 DBUtil.dbExecute( INS_GE34, insGE34Args, APP_INFO, DBID ); // 5.5.5.1 (2012/08/07) 196 } 197 } 198 199 /** 200 * パラメータマップをセットします。 201 * 202 * @param params パラメータのマップ 203 */ 204 205 /** 206 * パラメータからマップをセットします。 207 * 208 * @og.rev 5.9.3.0 (2015/11/30) files追加 209 * @og.rev 6.4.2.0 (2016/01/29) DateSet.getDate( String ) を利用するように修正します。 210 * @og.rev 6.4.3.1 (2016/02/12) PMD refactoring. Map → ConcurrentMap に置き換え。 211 * @og.rev 6.4.3.3 (2016/03/04) ConcurrentHashMap の not null制限のチェック追加 212 * 213 * @param systemId システムID(not null) 214 * @param from FROMアドレス(not null) 215 * @param tos TOアドレス(CSV形式) 216 * @param ccs CCアドレス(CSV形式) 217 * @param bccs BCCアドレス(CSV形式) 218 * @param content 本文 219 * @param title タイトル 220 * @param userid 登録ユーザ 221 * @param pgid 登録PG 222 * @param files 添付ファイル 223 */ 224 public void setInitParams( final String systemId, final String from, final String[] tos, final String[] ccs 225 ,final String[] bccs, final String content, final String title, final String userid, final String pgid 226 ,final String[] files ) { 227 228 // 6.4.3.3 (2016/03/04) ConcurrentHashMap の not null制限のチェック追加 229 if( systemId == null || from == null ) { 230 final String errMsg = "systemId または、from が null です。" 231 + " systemId=" + systemId + " , from=" + from ; 232 throw new OgRuntimeException( errMsg ); 233 } 234 235 initParamMap.clear(); 236 237 initParamMap.put( "SYSTEM_ID" , systemId ); 238 initParamMap.put( "FROM" , from ); 239 initParamMap.put( "TO" , StringUtil.array2csv( tos ) ); 240 initParamMap.put( "CC" , StringUtil.array2csv( ccs ) ); 241 initParamMap.put( "BCC" , StringUtil.array2csv( bccs ) ); 242 initParamMap.put( "CONTENT" , nval( content , "No Content" ) ); 243 initParamMap.put( "TITLE" , nval( title , "No Title" ) ); 244 initParamMap.put( "DATE" , DateSet.getDate("yyyy/MM/dd") ); // 6.4.2.0 (2016/01/29) 245 initParamMap.put( "TIME" , DateSet.getDate("HH:mm:ss") ); // 6.4.2.0 (2016/01/29) 246 initParamMap.put( "LOGIN_USERID", nval( userid , "No UserID" ) ); 247 initParamMap.put( "PGID" , nval( pgid , "No PGID" ) ); 248 initParamMap.put( "FILES" , StringUtil.array2csv( files ) ); // 5.9.3.0 (2015/12/04) 249 250 getDstMap( tos, ccs, bccs ); 251 } 252 253 /** 254 * 指定の長さ以内の文字列を返します。 255 * 256 * @og.rev 5.9.1.3 (2015/10/30) 文字数ではなくByte数に変更 257 * 258 * @param src オリジナルの文字列 259 * @param maxLen 指定の長さ 260 * 261 * @return 指定の長さに短縮された文字列 262 */ 263 private String trim( final String src, final int maxLen ) { 264 String rtn = src; 265 if( src != null && src.length() > maxLen ) { 266 rtn = StringUtil.cut( src, maxLen ); 267 } 268 return rtn; 269 } 270 271 /** 272 * 要求NOを採番します。 273 * この要求NOで履歴テーブル(GE32)と宛先テーブル(GE30)の関連付けを持たせます。 274 * 275 * @og.rev 5.5.5.1 (2012/08/07) リソース系DBID 付け忘れ対策 276 * @og.rev 5.9.31.1 (2018/04/13) シーケンスの取り方変更 277 * @og.rev 7.0.6.4 (2019/11/29) TransactionRealのclose漏れ対応 278 * 279 * @return 要求NO 280 */ 281 private String getYkno() { 282// final String[][] tmp = DBUtil.dbExecute( SEL_YKNO, new String[0], APP_INFO, DBID ); // 5.5.5.1 (2012/08/07) 283// if( tmp == null || tmp.length == 0 ) { 284// final String errMsg = "要求NO採番エラー" 285// + " SQL=" + SEL_YKNO ; // 5.1.8.0 (2010/07/01) errMsg 修正 286// throw new OgRuntimeException( errMsg ); 287// } 288// return tmp[0][0]; 289 290// final Transaction tran = new TransactionReal( APP_INFO ); 291// final int rtn_ykno = dbName.getSequence( SEL_YKNO,tran,DBID ); 292// return Integer.toString( rtn_ykno ); 293 294 try( final Transaction tran = new TransactionReal( APP_INFO ) ) { // 7.0.6.4 (2019/11/29) try-with-resources文 295 return Integer.toString( dbName.getSequence( SEL_YKNO,tran,DBID ) ); 296 } 297 catch( final Throwable ex ) { 298 final String errMsg = "要求NO採番エラー" 299 + " SQL=" + SEL_YKNO ; // 5.1.8.0 (2010/07/01) errMsg 修正 300 throw new OgRuntimeException( errMsg ); 301 } 302 } 303 304 /** 305 * 送信先のアドレスをセットします。 306 * 307 * @og.rev 6.4.3.1 (2016/02/12) インスタンス変数で初期化した、ConcurrentSkipListMap を使用します。 308 * 309 * @param toId 送信先TOのアドレス 310 * @param ccId 送信先CCのアドレス 311 * @param bccId 送信先BCCのアドレス 312 */ 313 private void getDstMap( final String[] toId, final String[] ccId, final String[] bccId ){ 314 // 送信先(TO、CC、BCC)のマップを初期化します。 315 mailDstMap.clear(); 316 317 // 送信先(TO、CC、BCC)のマップに、値をセットします。セット順ではなく、自然ソート順です。 318 setDstAddrMap( mailDstMap , bccId, KBN_BCC ); 319 setDstAddrMap( mailDstMap , ccId, KBN_CC ); 320 setDstAddrMap( mailDstMap , toId, KBN_TO ); 321 } 322 323 /** 324 * 送信先のアドレス・マップを作成します。 325 * 326 * @og.rev 6.4.3.1 (2016/02/12) インスタンス変数で初期化した、ConcurrentSkipListMap を使用します。 327 * @og.rev 6.4.3.3 (2016/03/04) ConcurrentHashMap を受け取ることを明確にするため、I/FをConcurrentMapに変更します。 328 * @og.rev 5.9.33.0 (2018/06/01) dstBufがnullの場合の処理 329 * 330 * @param dstMap 設定するMapオブジェクト 331 * @param dstBuf 送信先配列 332 * @param kbn 送信区分[0:TO/1:CC/2:BCC] 333 */ 334 private void setDstAddrMap( final ConcurrentMap<String, String[]> dstMap, final String[] dstBuf, final int kbn ){ 335 if( dstBuf != null && dstBuf.length > 0 ) { // 5.9.33.0 (2018/06/01) 336 // IDX_DST_ADDR ,IDX_DST_KBN 337 final String[] dstInit = { "", Integer.toString( kbn ) }; 338 339 final int len = dstBuf.length; 340 for( int i=0; i < len; i++ ){ 341 String[] indMember = dstInit.clone(); 342 indMember[IDX_DST_ADDR] = dstBuf[i]; // メールアドレス 343 344 dstMap.put( dstBuf[i], indMember ); 345 } 346 } 347 } 348}