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