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.taglib; 017 018import java.util.Locale; 019import java.util.Set; // 6.4.3.4 (2016/03/11) 020import java.util.Enumeration; 021import java.util.concurrent.ConcurrentMap; // 6.4.3.3 (2016/03/04) 022import java.util.concurrent.ConcurrentHashMap; // 6.4.3.3 (2016/03/04) 023 024import javax.servlet.ServletRequest ; 025 026import org.opengion.fukurou.system.DateSet; // 6.4.2.0 (2016/01/29) 027import org.opengion.fukurou.system.ThrowUtil; // 6.4.2.0 (2016/01/29) 028import org.opengion.fukurou.util.ErrorMessage; 029import org.opengion.fukurou.util.StringUtil; 030import org.opengion.fukurou.util.ToString; // 6.1.1.0 (2015/01/17) 031import org.opengion.fukurou.util.ArraySet; // 6.4.3.4 (2016/03/11) 032import org.opengion.hayabusa.common.HybsSystem; 033import org.opengion.hayabusa.common.HybsSystemException; 034import org.opengion.hayabusa.mail.MailManager_DIRECT; 035import org.opengion.hayabusa.db.DBTableModel; 036 037import static org.opengion.fukurou.util.StringUtil.nval; 038 039/** 040 * 定型文およびパラメータの設定によるメールを送信するためのタグです。 041 * 042 * @og.formSample 043 * ●形式:<og:mailSender ptnId="…" action="…" from="…" to="…" /> 044 * ●body:なし 045 * 046 * ●Tag定義: 047 * <og:mailSender2 048 * ptnId ○【TAG】メール定型文のIDを指定します(必須)。 049 * from ○【TAG】送信元(FROM)の社員IDを指定します(必須)。 050 * action ○【TAG】アクション[CHECK/SEND/NOCHECK]をセットします(必須)。 051 * addrCheck 【TAG】メールアドレスの構文とメールアカウントのチェックをするかどうか[true/false]を指定します 052 * to 【TAG】送信先(TO)の社員ID、グループIDをCSV形式で指定します 053 * cc 【TAG】送信先(CC)の社員ID、グループIDをCSV形式で指定します 054 * bcc 【TAG】送信先(BCC)の社員ID、グループIDをCSV形式で指定します 055 * tableId 【TAG】(通常は使いません)宛先のDBTableModelを、sessionに登録するときのキーを指定します 056 * scope 【TAG】キャッシュする場合のスコープ[request/page/session/application]を指定します(初期値:session) 057 * fileURL 【TAG】添付ファイルのセーブディレクトリを指定します (初期値:FILE_URL[=filetemp/]) 058 * filename 【TAG】添付ファイル名をCSV形式で指定します 059 * useStop 【TAG】例外発生した場合、後続JSPの評価を中止するかどうか[true:中止/false:継続]を指定します 060 * useSLabel 【TAG】7.0.7.0 (2019/12/13) エラーメッセージにSLABELを利用するかどうか[true/false]を指定します(初期値:false) 061 * debug 【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false) 062 * /> 063 * 064 * ●使用例 065 * <og:mailSender2 > 066 * ptnId = PtnId 定型文ID(定型文マスタに登録されている定型文ID) 067 * action = Action アクション(CHECK:確認あり/SEND:確認後の送信/NOCHECK:確認なし) 068 * from = From 送信元(送信者社員ID) 069 * to = To 送信先(コンマ区切りで複数セット可能、社員ID、グループID) 070 * cc = Cc 送信先(コンマ区切りで複数セット可能、社員ID、グループID) 071 * bcc = Bcc 送信先(コンマ区切りで複数セット可能、社員ID、グループID) 072 * fileURL = 添付ファイルのセーブディレクトリ 073 * filename = 添付ファイル名(ローカルにセーブされたファイル名)(コンマ区切りで複数登録可能) 074 * addrCheck = true/false(メールアカウントの有効チェック) 075 * useStop = true/false エラー発生時に後続JSPの評価を中止する(true)/中止しない(false) 076 * scope = request/session 宛先テーブルの格納スコープ(デフォルト:session) 077 * tableId = TableId 宛先テーブルのID(通常はデフォルトのテーブルモデルID名称を利用します) 078 * debug = true/false 079 * </og:mailSender > 080 * 081 * from には社員IDしかセットできません。 082 * to,cc,bccには社員ID、またはグループIDをコンマ区切りで複数セットできます。 083 * action:CHECK は送信前に、一度送信内容を確認したい場合に利用します。action=CHECKの場合、scopeにはsessionしかセットできません。 084 * action:SEND は確認済のメール文を送信する場合に利用します。 085 * action:NOCHECK は確認なしで送信したい場合に利用します。 086 * 087 * @og.group その他出力 088 * 089 * @version 4.0 090 * @author Sen.Li 091 * @since JDK1.6 092 */ 093public class MailSenderTag2 extends CommonTagSupport { 094 /** このプログラムのVERSION文字列を設定します。 {@value} */ 095 private static final String VERSION = "7.0.7.0 (2019/12/13)" ; 096 private static final long serialVersionUID = 707020191213L ; 097 098 private static final String ACT_CHECK = "CHECK" ; 099 private static final String ACT_SEND = "SEND" ; 100 private static final String ACT_NOCHECK = "NOCHECK" ; 101 // 6.4.3.4 (2016/03/11) String配列 から、Setに置き換えます。 102 private static final Set<String> ACTION_SET = new ArraySet<>( ACT_CHECK , ACT_SEND, ACT_NOCHECK ); 103 104 private static final int MAX_FILE_COUNT = 5 ; 105 private String ptnId ; 106 private String action ; 107 private String from ; 108 private String to ; 109 private String cc ; 110 private String bcc ; 111 private String fileURL = HybsSystem.sys( "FILE_URL" ); 112 private String[] filename ; 113 private String tableId = HybsSystem.TBL_MDL_KEY ; 114 private boolean addrCheck ; 115 private boolean useStop = true; 116 private boolean useSLabel ; // 7.0.7.0 (2019/12/13) エラーメッセージにSLABELを利用するかどうか[true/false]を指定します(初期値:false) 117 118 /** 119 * デフォルトコンストラクター 120 * 121 * @og.rev 6.4.2.0 (2016/01/29) PMD refactoring. Each class should declare at least one constructor. 122 */ 123 public MailSenderTag2() { super(); } // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。 124 125 /** 126 * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。 127 * 128 * @og.rev 6.3.4.0 (2015/08/01) Arrays.toString から String.join に置き換え。 129 * @og.rev 6.4.2.0 (2016/01/29) ex.printStackTrace() を、ThrowUtil#ogStackTrace(Throwable) に置き換え。 130 * @og.rev 6.4.3.3 (2016/03/04) ConcurrentHashMap を受け取ることを明確にするため、I/FをConcurrentMapに変更します。 131 * @og.rev 6.4.3.4 (2016/03/11) String配列 から、Setに置き換えます。 132 * @og.rev 6.5.0.1 (2016/10/21) ErrorMessage をまとめるのと、直接 Throwable を渡します。 133 * @og.rev 7.0.7.0 (2019/12/13) useSLabel 属性を追加。 134 * 135 * @return 後続処理の指示 136 */ 137 @Override 138 public int doEndTag() { 139 debugPrint(); 140 int rtnCode = EVAL_PAGE; 141 int errCode = ErrorMessage.OK; 142 143 if( check( action, ACTION_SET ) ) { 144 try { 145 tableId = ( tableId == null ) ? HybsSystem.TBL_MDL_KEY:tableId; 146 final MailManager_DIRECT manager = new MailManager_DIRECT(); 147 manager.setResourceManager( getResource() ); 148 DBTableModel table = null; 149 150 if( ACT_NOCHECK.equals( action ) || ACT_CHECK.equals( action ) ){ 151 final ConcurrentMap<String,String> initParamMap = makeParamMap(); // 6.4.3.3 (2016/03/04) 152 manager.create( initParamMap ); 153 } 154 if( ACT_NOCHECK.equals( action ) ) { 155 manager.setDebug( isDebug() ); 156 manager.send(); 157 } 158 else if( ACT_CHECK.equals( action ) ) { 159 setSessionAttribute( "MAIL.FROM_ADDR", manager.getFromAddr() ); 160 setSessionAttribute( "MAIL.PTN_ID", ptnId ); 161 setSessionAttribute( "MAIL.TITLE", manager.getTitle() ); 162 setSessionAttribute( "MAIL.CONTENT", manager.getContent() ); 163 } 164 else if( ACT_SEND.equals( action ) ) { 165 ptnId = (String) getSessionAttribute( "MAIL.PTN_ID" ); 166 final ConcurrentMap<String,String> initParamMap = makeParamMap(); // 6.4.3.3 (2016/03/04) 167 manager.setFromAddr( (String) getSessionAttribute( "MAIL.FROM_ADDR" ) ); 168 manager.setTitle( (String) getSessionAttribute( "MAIL.TITLE" ) ); 169 manager.setContent( (String) getSessionAttribute( "MAIL.CONTENT" ) ); 170 table = ( DBTableModel )getObject( tableId ); 171 manager.create( initParamMap, table ); 172 manager.setDebug( isDebug() ); 173 manager.send(); 174 } 175 startQueryTransaction( tableId ); 176 table = manager.makeDstTable(); 177 if( ! commitTableObject( tableId, table ) ) { 178 jspPrint( "DBTableModel は登録しません。" ); 179 } 180 } 181 catch( final RuntimeException rex ){ 182 if( useStop ) { 183 final ErrorMessage errMsg = new ErrorMessage(); 184 // 6.5.0.1 (2016/10/21) ErrorMessage をまとめるのと、直接 Throwable を渡します。 185 errMsg.addMessage( 0, ErrorMessage.NG, "ERR0040", rex.getMessage() ) 186 .addMessage( rex ); 187 188// jspPrint( TaglibUtil.makeHTMLErrorTable( errMsg, getResource() ) ); 189 jspPrint( TaglibUtil.makeHTMLErrorTable( errMsg, getResource(),useSLabel ) ); // 7.0.7.0 (2019/12/13) 190 rtnCode = SKIP_PAGE; 191 } 192 System.err.println( ThrowUtil.ogStackTrace( rex ) ); // 6.4.2.0 (2016/01/29) 193 errCode = ErrorMessage.WARNING; 194 } 195 setSessionAttribute( "MAIL.ERR_CODE", String.valueOf( errCode ) ); 196 } 197 else { 198 final String errMsg = "指定のアクションは実行できません。アクションエラー" + CR 199 + "action=[" + action + "] " + CR 200 + "actionList=" + String.join( ", " , ACTION_SET ) ; 201 throw new HybsSystemException( errMsg ); 202 } 203 return rtnCode; 204 } 205 206 /** 207 * タグリブオブジェクトをリリースします。 208 * キャッシュされて再利用されるので、フィールドの初期設定を行います。 209 * 210 * @og.rev 7.0.7.0 (2019/12/13) useSLabel 属性を追加。 211 */ 212 @Override 213 protected void release2() { 214 super.release2(); 215 from = null; 216 to = null; 217 cc = null; 218 bcc = null; 219 fileURL = HybsSystem.sys( "FILE_URL" ); 220 filename = null; 221 ptnId = null; 222 action = null; 223 tableId = HybsSystem.TBL_MDL_KEY ; 224 addrCheck = false; 225 useStop = true; 226 useSLabel = false; // 7.0.7.0 (2019/12/13) エラーメッセージにSLABELを利用するかどうか[true/false]を指定します(初期値:false) 227 } 228 229 /** 230 * 【TAG】アクション[CHECK/SEND/NOCHECK]をセットします。 231 * @og.tag 232 * 送信前に、一度送信内容を確認する場合、"CHECK "をセットします。 233 * 確認済のメール文を送信する場合、"SEND"をセットします。 234 * 確認なしで送信する場合、"NOCHECK"をセットします。 235 * 236 * @param act アクション [CHECK/SEND/NOCHECK] 237 */ 238 public void setAction( final String act ) { 239 final String act2 = getRequestParameter( act ); 240 if( act2 != null && act2.length() > 0 ) { action = act2.toUpperCase(Locale.JAPAN); } 241 } 242 243 /** 244 * 【TAG】メール定型文のIDを指定します。 245 * 246 * @og.tag 247 * 定型文マスタに定義されている定型文IDを指定します。 248 * 249 * @param pid 定型文ID 250 */ 251 public void setPtnId( final String pid ) { 252 ptnId = nval( getRequestParameter( pid ),null ); 253 } 254 255 /** 256 * 【TAG】送信元(FROM)の社員IDを指定します。 257 * 258 * @og.tag 259 * 送信元(FROM)の社員IDを指定します。社員マスタに存在している社員ID(例:"C12345")しかセットできません。 260 * 261 * @param fromId 送信元(FROM)の社員ID 262 */ 263 public void setFrom( final String fromId ) { 264 from = nval( getRequestParameter( fromId ), from ); 265 setRequestAttribute( "FROM", from ); 266 } 267 268 /** 269 * 【TAG】送信先(TO)の社員ID、グループIDをCSV形式で指定します。 270 * 271 * @og.tag 272 * 複数のID(社員ID、グループID)をCSV形式でセットできます。 273 * グループIDはグループマスタ管理画面により定義する必要があります。"GP.XXXXX"の形式でセットします。 274 * 275 * @param toIds 送信先(TO)の社員ID、グループID(CSV形式) 276 */ 277 public void setTo( final String toIds ) { 278 to = getRequestParameter( toIds ); 279 } 280 281 /** 282 * 【TAG】送信先(CC)の社員ID、グループIDをCSV形式で指定します。 283 * 284 * @og.tag 285 * 複数のID(社員ID、グループID)をCSV形式でセットできます。 286 * グループIDはグループマスタ管理画面により定義する必要があります。"GP.XXXXX"の形式でセットします。 287 * 288 * @param ccIds 送信先(CC)の社員ID、グループID(CSV形式) 289 */ 290 public void setCc( final String ccIds ) { 291 cc = getRequestParameter( ccIds ); 292 } 293 294 /** 295 * 【TAG】送信先(BCC)の社員ID、グループIDをCSV形式で指定します。 296 * 297 * @og.tag 298 * 複数のID(社員ID、グループID)をCSV形式でセットできます。 299 * グループIDはグループマスタ管理画面により定義する必要があります。"GP.XXXXX"の形式でセットします。 300 * 301 * @param bccIds 送信先(BCC)の社員ID、グループID(CSV形式) 302 */ 303 public void setBcc( final String bccIds ) { 304 bcc = getRequestParameter( bccIds ); 305 } 306 307 /** 308 * 【TAG】添付ファイルのセーブディレクトリを指定します 309 * (初期値:FILE_URL[={@og.value SystemData#FILE_URL}])。 310 * 311 * @og.tag 312 * この属性で指定されるディレクトリに、添付ファイルが存在すると仮定します。 313 * 指定方法は、通常の fileURL 属性と同様に、先頭が、'/' (UNIX) または、2文字目が、 314 * ":" (Windows)の場合は、指定のURLそのままのディレクトリに、そうでない場合は、 315 * fileURL = "{@USER.ID}" と指定すると、FILE_URL 属性で指定のフォルダの下に、 316 * さらに、各個人ID別のフォルダを作成して、そこを使用します。 317 * (初期値:システム定数のFILE_URL[={@og.value SystemData#FILE_URL}])。 318 * 319 * @og.rev 6.4.2.1 (2016/02/05) URLの最後に、"/" を追加する処理を廃止。 320 * 321 * @param url 添付ファイルのセーブディレクトリ 322 * @see org.opengion.hayabusa.common.SystemData#FILE_URL 323 */ 324 public void setFileURL( final String url ) { 325 final String furl = nval( getRequestParameter( url ),null ); 326 if( furl != null ) { 327 fileURL = StringUtil.urlAppend( fileURL,furl ); 328 } 329 } 330 331 /** 332 * 【TAG】添付ファイル名をCSV形式で指定します。 333 * 334 * @og.tag 335 * 複数ファイルをセットできます。 336 * 設定方法は、カンマで区切って並べ複数指定できます。 337 * 338 * @param fname 添付ファイル名 339 */ 340 public void setFilename( final String fname ) { 341 filename = StringUtil.csv2ArrayOnly( getRequestParameter( fname ) ); 342 } 343 344 /** 345 * 【TAG】メールアドレスの構文とメールアカウントのチェックをするかどうか[true:する/false:しない]を指定します。 346 * 347 * @og.tag 348 * メールアドレスの構文とメールアカウントのチェック[true:する/false:しない]を指定します。 349 * メール文合成の段階では、メールアドレスの構文文法についてチェックします。 350 * メール送信の段階では、メールアカウントが有効かについてチェックします。 351 * "true"と指定する場合、エラーが検出されたら、例外を投げて本タグの処理が中止されます。 352 * "false"と指定する場合、エラーが検出されても、例外を投げません。 353 * 354 * @param addrChk 構文,アカウントチェック可否 [true:する/false:しない] 355 */ 356 public void setAddrCheck( final String addrChk ) { 357 addrCheck = nval( getRequestParameter( addrChk ), addrCheck ); 358 } 359 360 /** 361 * 【TAG】例外発生した場合、後続JSPの評価を中止するかどうか[true:中止/false:継続]を指定します。 362 * 363 * @og.tag 364 * "true"と指定する場合、例外が発生したら、後続JSPが評価されません。 365 * "false"と指定する場合、例外が発生しても、後続JSPが評価されます。後続のJSPでは変数 366 * {@MAIL.ERR_CODE}で本タグの実行状況(エラー発生したか)を取得できます。 367 * 368 * @param stop 例外時に後続処理を中止可否 [true:中止/false:継続] 369 */ 370 public void setUseStop( final String stop ) { 371 useStop = nval( getRequestParameter( stop ), useStop ); 372 } 373 374 /** 375 * 【TAG】(通常は使いません)結果のDBTableModelを、sessionに登録するときのキーを指定します 376 * (初期値:HybsSystem#TBL_MDL_KEY[={@og.value HybsSystem#TBL_MDL_KEY}])。 377 * 378 * @og.tag 379 * 検索結果より、DBTableModelオブジェクトを作成します。これを、下流のviewタグ等に 380 * 渡す場合に、通常は、session を利用します。その場合の登録キーです。 381 * query タグを同時に実行して、結果を求める場合、同一メモリに配置される為、 382 * この tableId 属性を利用して、メモリ空間を分けます。 383 * (初期値:HybsSystem#TBL_MDL_KEY[={@og.value HybsSystem#TBL_MDL_KEY}])。 384 * 385 * @param id テーブルID (sessionに登録する時のID) 386 */ 387 public void setTableId( final String id ) { 388 tableId = nval( getRequestParameter( id ),tableId ); // 3.8.0.9 (2005/10/17) 389 } 390 391 /** 392 * 【TAG】エラーメッセージにSLABELを利用するかどうか[true/false]を指定します(初期値:false)。 393 * 394 * @og.tag 395 * 通常のエラーメッセージは、ラベル(長)が使われますが、これをラベル(短)を使いたい場合に、true にセットします。 396 * ここでのラベル(短)は、タグ修飾なしの、ラベル(短)です。 397 * 標準はfalse:利用しない=ラベル(長)です。 398 * true/false以外を指定した場合はfalse扱いとします。 399 * 400 * ラベルリソースの概要説明があれば表示しますが、useSLabel="true" 時は、概要説明を表示しません。 401 * 402 * @og.rev 7.0.7.0 (2019/12/13) 新規追加 403 * 404 * @param prm SLABEL利用 [true:利用する/false:利用しない] 405 */ 406 public void setUseSLabel( final String prm ) { 407 useSLabel = nval( getRequestParameter( prm ),useSLabel ); 408 } 409 410 /** 411 * リクエスト変数の値より、定型文に必要なパラメータを取得して、パレメータマップに入れます。 412 * パラメータマップは引数としてメールモジュールのマネージャに渡します。 413 * マネージャの中には、定型文を元に、パラメータマップの値とマージしてメールの各項目を合成します。 414 * 415 * @og.rev 6.4.2.0 (2016/01/29) DateSet.getDate( String ) を利用するように修正します。 416 * @og.rev 6.4.3.3 (2016/03/04) ConcurrentHashMap を受け取ることを明確にするため、I/FをConcurrentMapに変更します。 417 * 418 * @return 定型文に必要なパレメータマップ 419 */ 420 private ConcurrentMap<String, String> makeParamMap() { 421 final ConcurrentMap<String, String> paramMap = new ConcurrentHashMap<>(); 422 if( action.endsWith( ACT_NOCHECK ) || action.equals( ACT_CHECK ) ) { 423 final ServletRequest request = this.getRequest(); 424 final Enumeration<?> enu1 = request.getAttributeNames(); 425 while( enu1.hasMoreElements() ) { 426 final String name = (String) enu1.nextElement(); 427 final Object tmpObj = request.getAttribute( name ); 428 if( tmpObj instanceof String ) { 429 putNotNull( paramMap,name,(String)tmpObj ); 430 } 431 } 432 final Enumeration<?> enu2 = request.getParameterNames(); 433 while( enu2.hasMoreElements() ) { 434 final String name = (String) enu2.nextElement(); 435 putNotNull( paramMap,name,request.getParameter( name ) ); 436 } 437 438 putNotNull( paramMap,"FROM" , from ); 439 putNotNull( paramMap,"TO" , to ); 440 putNotNull( paramMap,"CC" , cc ); 441 putNotNull( paramMap,"BCC" , bcc ); 442 } 443 444 putNotNull( paramMap,"PTN_ID" , ptnId ); 445 putNotNull( paramMap,"SYSTEM_ID" , HybsSystem.sys( "SYSTEM_ID" ) ); 446 putNotNull( paramMap,"ADDR_CHECK" , String.valueOf( addrCheck ) ); 447 putNotNull( paramMap,"LOGIN_USERID" , getRequestValue( "USER.ID" ) ); 448 putNotNull( paramMap,"LOGIN_USERNAME" , getRequestValue( "USER.JNAME" ) ); 449 putNotNull( paramMap,"PGID" , getRequestValue( "GUI.KEY" ) ); 450 putNotNull( paramMap,"DATE" , DateSet.getDate( "yyyy/MM/dd" ) ); // 6.4.2.0 (2016/01/29) 451 putNotNull( paramMap,"TIME" , DateSet.getDate( "HH:mm:ss" ) ); // 6.4.2.0 (2016/01/29) 452 453 String[] temp = { "", "", "", "", "" }; 454 if( filename != null && filename.length > 0 ) { 455 final String directory = HybsSystem.url2dir( fileURL ); 456 final int fileCount = filename.length > MAX_FILE_COUNT ? MAX_FILE_COUNT : filename.length; 457 for( int i=0; i<fileCount; i++ ) { 458 temp[i] = StringUtil.urlAppend( directory, filename[i] ); 459 } 460 } 461 putNotNull( paramMap,"ATTACH1", temp[0] ); 462 putNotNull( paramMap,"ATTACH2", temp[1] ); 463 putNotNull( paramMap,"ATTACH3", temp[2] ); 464 putNotNull( paramMap,"ATTACH4", temp[3] ); 465 putNotNull( paramMap,"ATTACH5", temp[4] ); 466 467 return paramMap; 468 } 469 470 /** 471 * ConcurrentMapのnot null制限を回避するため、key,val が、not nullのときだけ、Mapにput します。 472 * 473 * @og.rev 6.4.3.3 (2016/03/04) ConcurrentHashMap を受け取ることを明確にするため、I/FをConcurrentMapに変更します。 474 * 475 * @param cmap putする元となるConcurrentMap 476 * @param key putするときのキー 477 * @param val putするときの値 478 */ 479 private final void putNotNull( final ConcurrentMap<String, String> cmap , final String key , final String val ) { 480 if( key != null && val != null ) { cmap.put( key,val ); } 481 } 482 483 /** 484 * このオブジェクトの文字列表現を返します。 485 * 基本的にデバッグ目的に使用します。 486 * 487 * @return このクラスの文字列表現 488 * @og.rtnNotNull 489 */ 490 @Override 491 public String toString() { 492 return ToString.title(this.getClass().getName() ) 493 .println( "VERSION" ,VERSION ) 494 .println( "ptnId" ,ptnId ) 495 .println( "action" ,action ) 496 .println( "tableId" ,tableId ) 497 .println( "addrCheck" ,addrCheck ) 498 .println( "useStop" ,useStop ) 499 .println( "from" ,from ) 500 .println( "to" ,to ) 501 .println( "cc" ,cc ) 502 .println( "bcc" ,bcc ) 503 .println( "filename" ,filename ) 504 .println( "fileURL" ,fileURL ) 505 .println( "Other...", getAttributes().getAttribute() ) 506 .fixForm().toString(); 507 } 508}