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