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 * 203 * @param params パラメータのマップ 204 */ 205 206 /** 207 * パラメータからマップをセットします。 208 * 209 * @og.rev 5.9.3.0 (2015/11/30) files追加 210 * @og.rev 6.4.2.0 (2016/01/29) DateSet.getDate( String ) を利用するように修正します。 211 * @og.rev 6.4.3.1 (2016/02/12) PMD refactoring. Map → ConcurrentMap に置き換え。 212 * @og.rev 6.4.3.3 (2016/03/04) ConcurrentHashMap の not null制限のチェック追加 213 * 214 * @param systemId システムID(not null) 215 * @param from FROMアドレス(not null) 216 * @param tos TOアドレス(カンマ区切り) 217 * @param ccs CCアドレス(カンマ区切り) 218 * @param bccs BCCアドレス(カンマ区切り) 219 * @param content 本文 220 * @param title タイトル 221 * @param userid 登録ユーザ 222 * @param pgid 登録PG 223 * @param files 添付ファイル 224 */ 225 public void setInitParams( final String systemId, final String from, final String[] tos, final String[] ccs 226 ,final String[] bccs, final String content, final String title, final String userid, final String pgid 227 ,final String[] files ) { 228 229 // 6.4.3.3 (2016/03/04) ConcurrentHashMap の not null制限のチェック追加 230 if( systemId == null || from == null ) { 231 final String errMsg = "systemId または、from が null です。" 232 + " systemId=" + systemId + " , from=" + from ; 233 throw new OgRuntimeException( errMsg ); 234 } 235 236 initParamMap.clear(); 237 238 initParamMap.put( "SYSTEM_ID" , systemId ); 239 initParamMap.put( "FROM" , from ); 240 initParamMap.put( "TO" , StringUtil.array2csv( tos ) ); 241 initParamMap.put( "CC" , StringUtil.array2csv( ccs ) ); 242 initParamMap.put( "BCC" , StringUtil.array2csv( bccs ) ); 243 initParamMap.put( "CONTENT" , nval( content , "No Content" ) ); 244 initParamMap.put( "TITLE" , nval( title , "No Title" ) ); 245 initParamMap.put( "DATE" , DateSet.getDate("yyyy/MM/dd") ); // 6.4.2.0 (2016/01/29) 246 initParamMap.put( "TIME" , DateSet.getDate("HH:mm:ss") ); // 6.4.2.0 (2016/01/29) 247 initParamMap.put( "LOGIN_USERID", nval( userid , "No UserID" ) ); 248 initParamMap.put( "PGID" , nval( pgid , "No PGID" ) ); 249 initParamMap.put( "FILES" , StringUtil.array2csv( files ) ); // 5.9.3.0 (2015/12/04) 250 251 getDstMap( tos, ccs, bccs ); 252 } 253 254 /** 255 * 指定の長さ以内の文字列を返します。 256 * 257 * @og.rev 5.9.1.3 (2015/10/30) 文字数ではなくByte数に変更 258 * 259 * @param src オリジナルの文字列 260 * @param maxLen 指定の長さ 261 * 262 * @return 指定の長さに短縮された文字列 263 */ 264 private String trim( final String src, final int maxLen ) { 265 String rtn = src; 266 if( src != null && src.length() > maxLen ) { 267 rtn = StringUtil.cut( src, maxLen ); 268 } 269 return rtn; 270 } 271 272 /** 273 * 要求NOを採番します。 274 * この要求NOで履歴テーブル(GE32)と宛先テーブル(GE30)の関連付けを持たせます。 275 * 276 * @og.rev 5.5.5.1 (2012/08/07) リソース系DBID 付け忘れ対策 277 * @og.rev 5.9.31.1 (2018/04/13) シーケンスの取り方変更 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 295 /** 296 * 送信先のアドレスをセットします。 297 * 298 * @og.rev 6.4.3.1 (2016/02/12) インスタンス変数で初期化した、ConcurrentSkipListMap を使用します。 299 * 300 * @param toId 送信先TOのアドレス 301 * @param ccId 送信先CCのアドレス 302 * @param bccId 送信先BCCのアドレス 303 */ 304 private void getDstMap( final String[] toId, final String[] ccId, final String[] bccId ){ 305 // 送信先(TO、CC、BCC)のマップを初期化します。 306 mailDstMap.clear(); 307 308 // 送信先(TO、CC、BCC)のマップに、値をセットします。セット順ではなく、自然ソート順です。 309 setDstAddrMap( mailDstMap , bccId, KBN_BCC ); 310 setDstAddrMap( mailDstMap , ccId, KBN_CC ); 311 setDstAddrMap( mailDstMap , toId, KBN_TO ); 312 } 313 314 /** 315 * 送信先のアドレス・マップを作成します。 316 * 317 * @og.rev 6.4.3.1 (2016/02/12) インスタンス変数で初期化した、ConcurrentSkipListMap を使用します。 318 * @og.rev 6.4.3.3 (2016/03/04) ConcurrentHashMap を受け取ることを明確にするため、I/FをConcurrentMapに変更します。 319 * @og.rev 5.9.33.0 (2018/06/01) dstBufがnullの場合の処理 320 * 321 * @param dstMap 設定するMapオブジェクト 322 * @param dstBuf 送信先配列 323 * @param kbn 送信区分[0:TO/1:CC/2:BCC] 324 */ 325 private void setDstAddrMap( final ConcurrentMap<String, String[]> dstMap, final String[] dstBuf, final int kbn ){ 326 if( dstBuf != null && dstBuf.length > 0 ) { // 5.9.33.0 (2018/06/01) 327 // IDX_DST_ADDR ,IDX_DST_KBN 328 final String[] dstInit = { "", Integer.toString( kbn ) }; 329 330 final int len = dstBuf.length; 331 for( int i=0; i < len; i++ ){ 332 String[] indMember = dstInit.clone(); 333 indMember[IDX_DST_ADDR] = dstBuf[i]; // メールアドレス 334 335 dstMap.put( dstBuf[i], indMember ); 336 } 337 } 338 } 339}