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 static org.opengion.fukurou.util.StringUtil.nval; 019 020import java.util.List; 021import java.util.ArrayList; 022import java.util.Map; 023import java.util.LinkedHashMap; 024import java.util.Collections; 025import java.util.Locale ; // 6.7.6.1 (2017/03/17) 026import java.util.concurrent.ConcurrentMap; // 6.7.8.0 (2017/04/21) 027import java.util.concurrent.ConcurrentHashMap; // 6.7.8.0 (2017/04/21) 028 029import org.opengion.hayabusa.common.HybsSystem; 030import org.opengion.hayabusa.db.DBTableModel; 031import org.opengion.fukurou.util.ToString; // 6.8.5.0 (2018/01/09) 032 033import static org.opengion.hayabusa.taglib.ValueMapParamTag.VMP_KEYS; // 6.7.8.0 (2017/04/21) 034 035/** 036 * DBTableModelオブジェクトから、指定のキー情報と、レコードから、Mapオブジェクトを作成し、それを、 037 * BODY部のフォーマットに対応して、出力します。 038 * 039 * valueタグの、command="MAPOBJ" や、ALL_MAPOBJ に相当する処理を、複数キーと行レベルのデータで 040 * 管理します。 041 * 042 * 設定した値は、Mapを優先した、特殊な、{@XXXX} 形式で 取り出すことができます。 043 * 044 * keys で、CSV形式でカラム名を指定し、これらを、連結した文字列を、Mapのキー情報に使います。 045 * Mapの値情報は、そのレコードの配列になります。 046 * keys を指定しない場合は、最初のカラムの値が、キーになります。 047 * キーが重複する場合、先に現れたデータが優先されます。 048 * 049 * 値の取出し方法は、キーに対して、{@XXXX} 形式を、適用します。 050 * Map に存在しないキーは、リクエスト変数や、通常のvalus変数を見ます。 051 * valClm で、{@XXXX} 形式で取り出す値のカラムを指定できます。 052 * valClm を指定しない場合は、2番目のカラムを使用します。 053 * 054 * 特殊機能 055 * ・holdTag属性:{@XXXX} を、指定のタグで囲います。 056 * 例えば、holdTag="span" とすると、<span class="YYYYの値" >XXXXの値</span> 057 * という文字列を作成します。 058 * ・clsClms属性:先の指定のタグで囲う場合、そのタグのclass属性を指定できます。 059 * 複数指定した場合は、スペースで、連結します。 060 * ・{@XXXX cls="B"} とすると、個別の clsClms の値を使用せず、この値を、class属性として使います。 061 * clsClms と同様に、holsTag属性を指定しておく必要があります。 062 * ・tipsClms属性:先の指定のタグで囲う場合、そのタグのtitle属性を指定できます。 063 * マウスオーバーで、チップス表示されます。 064 * ・{@XXXX tips="YYYY"} とすると、個別の tipsClms の値を使用せず、この値を、title属性として使います。 065 * tipsClms と同様に、holsTag属性を指定しておく必要があります。 066 * ・nnClms属性:この属性で指定された値が、nullの場合、{@XXXX} の解析を行いません。 067 * 正確に言うと、Mapに取り込みません。この場合、先のholdTag属性で指定したタグそのものも 068 * 出力しません。 069 * ・{@XXXX* str="val"} とすると、キーワードのあいまい検索部分に、strで指定した 070 * val文字列が存在する場合のみ有効とします。 071 * ・キーに対して、Mapは、行データ全部を持っています。{@XXXX} は、最初のカラムの値です。 072 * ・2番目を取得する場合は、{@XXXX 1}と、3番目は、{@XXXX 2}と指定します。 073 * ・{@XXXX*} を指定すると、キーのあいまい検索で、キーそのものを複数選択することが出来ます。 074 * この場合、spanタグで囲う機能と併用すると、複数のspanタグを持つ文字列を合成できます。 075 * この特定のタグは、holdTag 属性で指定します。 076 * このキーのあいまい検索で、表示する順番は、DBTableModelでMapに読み込んだ順番になります。 077 * {@XXXX* 2} のような、取得カラムの指定も可能です。 078 * 取得カラムの指定も可能ですが、カラム番号は、常に一番最後に記述してください。 079 * ・{@XXXX!*} とすると、表示する順番を、逆順にすることが出来ます。取得カラムの指定も可能です。 080 * ・{@$XXXX} とすると、holdTagも、clsClms も使用せず、設定値のみ出力します。 081 * この場合は、固定値になるため、holsTagも、clsClms も使用しません。 082 * ・{@*XXXX!*} とすると、キーのあいまい指定の残り部分の文字列を出力します。連番の場合の番号を取り出せます。 083 * ・{@^XXXX} とすると、request.getAttribute()の値を優先して使用します。{@^XXXX*}などのあいまい指定も可能です。 084 * この場合、オリジナルのキーは、DBTableModel上に必要です。値の入れ替えのみ、行う感じです。 085 * 086 * ※ このタグは、Transaction タグの対象です。 087 * 088 * @og.formSample 089 * ●形式:<og:valueMap /> 090 * ●body:あり(EVAL_BODY_BUFFERED:BODYを評価し、{@XXXX} を特殊な方法で解析します) 091 * 092 * ●Tag定義: 093 * <og:valueMap 094 * keys 【TAG】パラメータから取り出すキーとなるカラム名を、CSV形式で指定します(初期値:最初のカラム) 095 * valClm 【TAG】パラメータから取り出す値のカラム名を指定します(初期値:2番目のカラム) 096 * holdTag 【TAG】値の前後を、指定のタグで挟みます 097 * clsClms 【TAG】holdTagを使用するとき、そのタグの属性にclass属性を出力する場合のカラム名をCSV形式で指定します 098 * tipsClms 【TAG】holdTagを使用するとき、そのタグの属性にtitle属性を出力する場合のカラム名をCSV形式で指定します 099 * nnClms 【TAG】パラメータが NULL の時に、設定しないカラム名を、CSV形式で指定します 100 * reqAttUpClms 【TAG】{@^XXXX}使用時に request.getAttribute() をセットすると同時に設定するカラム名をCSV形式で指定します 6.9.2.0 (2018/03/05) 101 * selectedAll 【TAG】データを全件選択済みとして処理するかどうか[true/false]を指定します(初期値:true) 102 * separator 【TAG】キーとなるカラム名の値を連結する項目区切り文字をセットします(初期値:"_") 103 * tableId 【TAG】sessionから取得する DBTableModelオブジェクトの ID(初期値:HybsSystem.TBL_MDL_KEY) 104 * scope 【TAG】DBTableModelオブジェクトを取得する場合の、scope(初期値:session) 105 * xssCheck 【TAG】パラメータの HTMLTag開始/終了文字(><) 存在チェックを実施するかどうか[true/false]を設定します (初期値:USE_XSS_CHECK[=true]) 106 * caseKey 【TAG】このタグ自体を利用するかどうかの条件キーを指定します(初期値:null) 107 * caseVal 【TAG】このタグ自体を利用するかどうかの条件値を指定します(初期値:null) 108 * caseNN 【TAG】指定の値が、null/ゼロ文字列 でない場合(Not Null=NN)は、このタグは使用されます(初期値:判定しない) 109 * caseNull 【TAG】指定の値が、null/ゼロ文字列 の場合は、このタグは使用されます(初期値:判定しない) 110 * caseIf 【TAG】指定の値が、true/TRUE文字列の場合は、このタグは使用されます(初期値:判定しない) 111 * debug 【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false) 112 * > ... Body ... 113 * </og:valueMap> 114 * 115 * ●使用例 116 * <og:query command="{@command}" debug="{@debug}" maxRowCount="{@maxRowCount}"> 117 * select CLM,NAME_JA,LABEL_NAME,KBSAKU,SYSTEM_ID,LANG, 118 * FGJ,USRSET,DYSET,USRUPD,DYUPD 119 * from GF41 120 * <og:where> 121 * <og:and value = "SYSTEM_ID = '{@SYSTEM_ID}'" /> 122 * <og:and value = "LANG = '{@LANG}'" /> 123 * <og:and value = "CLM like '{@CLM}'" /> 124 * <og:and value = "NAME_JA like '{@NAME_JA}'" /> 125 * <og:and value = "LABEL_NAME like '{@LABEL_NAME}'" /> 126 * <og:and value = "KBSAKU = '{@KBSAKU}'" /> 127 * </og:where> 128 * <og:appear startKey = "order by" value = "{@ORDER_BY}" 129 * defaultVal = "SYSTEM_ID,CLM,LANG" /> 130 * </og:query> 131 * 132 * <og:valueMap keys="SYSTEM_ID,CLM" holdTag="div" separator="_" clsClms="LANG,FGJ" > 133 * {@XX_AA0001} <br /> SYSTEM_IDとCLMの値を、separatorで連結。値は、キーの次(LABEL_NAME) 134 * {@XX_AA0001 1} <br /> 行番号の2番目(上のSQLではNAME_JA)の値 135 * {@XX_AA0001 2} <br /> 行番号の3番目(上のSQLではLABEL_NAME)の値 136 * 137 * {@XX_AA001* 2} <br /> キーの前方一致する行の3番目の値 138 * 139 * {@XX_AA000!* 1} キーの前方一致する行の2番目の値を、逆順で表示 140 * 141 * </og:valueMap> 142 * 143 * ・ キーは、select文の1番目のカラム 144 * <og:og:valueMap > ・・・フォーマット・・・ </og:valueMap> 145 * ・ キーが複数で、ユニークになる。(keys) 146 * <og:og:valueMap keys="SYSTEM_ID,CLM" > ・・・フォーマット・・・ </og:valueMap> 147 * ・ 値をdivタグで囲う。(holdTag) 148 * <og:og:valueMap keys="SYSTEM_ID,CLM" holdTag="div" > ・・・フォーマット・・・ </og:valueMap> 149 * ・ キーの連結のセパレータを指定。(separator) 150 * <og:og:valueMap keys="SYSTEM_ID,CLM" holdTag="div" separator="_" > ・・・フォーマット・・・ </og:valueMap> 151 * ・ 値をdivタグで囲う時に、クラス属性を追加します。(clsClms) 152 * <og:og:valueMap keys="SYSTEM_ID,CLM" holdTag="div" separator="_" clsClms="LANG,FGJ" > ・・・フォーマット・・・ </og:valueMap> 153 * ・ 値をdivタグで囲う時に、チップス表示(title属性)を追加します。(tipsClms) 154 * <og:og:valueMap keys="SYSTEM_ID,CLM" holdTag="div" separator="_" clsClms="LANG,FGJ" tipsClms="NAME_JA,LABEL_NAME" > ・・・フォーマット・・・ </og:valueMap> 155 * 156 * @og.group その他部品 157 * @og.rev 6.7.1.0 (2017/01/05) 新規作成 158 * 159 * @version 6.7 160 * @author Kazuhiko Hasegawa 161 * @since JDK8.0, 162 */ 163public class ValueMapTag extends CommonTagSupport { 164 /** このプログラムのVERSION文字列を設定します。 {@value} */ 165 private static final String VERSION = "7.4.2.3 (2021/06/09)" ; 166 private static final long serialVersionUID = 742320210609L ; 167 168 private static final String CLS_KEY = "cls=" ; // 6.7.3.0 (2017/01/27) cls指定のキーワード 169 private static final String TIPS_KEY = "tips=" ; // 6.7.3.0 (2017/01/27) tips指定のキーワード 170 private static final String STR_KEY = "str=" ; // 6.8.0.1 (2017/06/30) str指定のキーワード 171 172 private static final String NONE1 = "<style type=\"text/css\">." ; // 6.7.8.0 (2017/04/21) 173 private static final String NONE2 = " { display : none ;} </style>" ; // 6.7.8.0 (2017/04/21) 174 175 // 6.9.8.0 (2018/05/28) FindBugs:直列化可能クラスの非 transient で非直列化可能なインスタンスフィールド 176 private transient DBTableModel table ; 177 178 private String tableId = HybsSystem.TBL_MDL_KEY; 179 private boolean selectedAll = true; 180 private String keys ; 181 private String valClm ; // 6.7.2.0 (2017/01/16) 182 private String nnClms ; // このカラムの値が、nullのレコードは、使用しません。 183 private String holdTag ; // nullの場合は、なにもはさまない。 184 private String clsClms ; // holdTagで指定したタグの属性に、class属性を追加します。 185 private String tipsClms ; // 6.7.3.0 (2017/01/27) holdTagで指定したタグの属性に、title属性を追加します。 186 private String reqAttUpClms; // 6.9.2.0 (2018/03/05) request.getAttribute() をセットすると同時に設定するカラム名 187 private String[] reqAttClms ; // 6.9.2.0 (2018/03/05) reqAttUpClms を、配列に分解したもの 188 private String scope = "session"; // "request","session" 189 private String separator = "_"; // 項目区切り文字 190 private boolean xssCheck = HybsSystem.sysBool( "USE_XSS_CHECK" ); // 5.1.7.0 (2010/06/01) XSS対策 191 192 private int[] clsClmsNo ; // clsClmsが指定されない場合は、長さゼロの配列 193 private int[] tipsClmsNo ; // 6.7.3.0 (2017/01/27) tipsClmsが指定されない場合は、長さゼロの配列 194 private int[] reqAttClmsNo; // 6.9.2.0 (2018/03/05) reqAttUpClmsが指定されない場合は、長さゼロの配列 195 private int valClmNo = 1; // valClmが指定されない場合は、2番目のカラム(=1)の値を使用します。 196 197 private String body ; // パラメータ処理済みのBODY部分の文字列 198 private String restChangeKey ; // ValueMapParamTag で置き換え処理を行うキーワード 199 private boolean useNoneClsKey ; // mapObj の残り処理をおこなうかどうか(true:行う) 200 201 // synchronizedMap にする必要性があるのか無いのか、よく判っていません。 202 /** Collections.synchronizedMap で、同期します。テーブルの行の取得順に、Mapに追加していきます。(先に登録したデータが有効) */ 203 private final Map<String,String[]> mapObj = Collections.synchronizedMap( new LinkedHashMap<>() ); 204 205 // ValueMapParamTagから受け取った、各種設定情報を、管理するMapオブジェクト。 206 private final ConcurrentMap<VMP_KEYS,String> paramMap = new ConcurrentHashMap<>(); 207 208 // ValueMapParamTag で使用する、未使用のキーワードを管理するMap 209 /** Collections.synchronizedMap で、同期します。テーブルの行の取得順に、Mapに追加していきます。(先に登録したデータが有効) */ 210 private final Map<String,String[]> restMap = Collections.synchronizedMap( new LinkedHashMap<>() ); 211 212 /** 213 * デフォルトコンストラクター 214 * 215 * @og.rev 6.7.1.0 (2017/01/05) 新規作成 216 * 217 */ 218 public ValueMapTag() { super(); } // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。 219 220 /** 221 * Taglibの開始タグが見つかったときに処理する doStartTag() を オーバーライドします。 222 * 223 * @og.rev 6.7.1.0 (2017/01/05) 新規作成 224 * 225 * @return 後続処理の指示 226 */ 227 @Override 228 public int doStartTag() { 229 if( useTag() ) { 230 useXssCheck( xssCheck ); 231 table = (DBTableModel)getObject( tableId ); 232 if( table != null && table.getRowCount() > 0 && table.getColumnCount() > 0 ) { 233 makeMapObj( table ); // Body の評価前にMapを作成する必要がある。 234 235 return EVAL_BODY_BUFFERED ; // Body を評価する 236 } 237 } 238 return SKIP_BODY ; // Body を評価しない 239 } 240 241 /** 242 * Taglibのタグ本体を処理する doAfterBody() を オーバーライドします。 243 * 244 * @og.rev 6.7.1.0 (2017/01/05) 新規作成 245 * 246 * @return 後続処理の指示(SKIP_BODY) 247 */ 248 @Override 249 public int doAfterBody() { 250 body = getBodyString(); 251 252 return SKIP_BODY ; 253 } 254 255 /** 256 * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。 257 * 258 * @og.rev 6.7.1.0 (2017/01/05) 新規作成 259 * 260 * @return 後続処理の指示 261 */ 262 @Override 263 public int doEndTag() { 264 debugPrint(); // 4.0.0 (2005/02/28) 265 if( useTag() && body != null ) { 266 jspPrint( body ); 267 } 268 269 // mapObj の残り処理が必要かどうか。mapObj が空で、NONE_CLS_KEY が存在する場合は、残を隠す。 270 if( useNoneClsKey ) { 271 final String noneClassKey = paramMap.get( VMP_KEYS.NONE_CLS_KEY ); 272 jspPrint( NONE1 + noneClassKey + NONE2 ); 273 } 274 275 return EVAL_PAGE ; 276 } 277 278 /** 279 * タグリブオブジェクトをリリースします。 280 * キャッシュされて再利用されるので、フィールドの初期設定を行います。 281 * 282 * @og.rev 6.7.1.0 (2017/01/05) 新規作成 283 * @og.rev 6.7.2.0 (2017/01/16) valClm 追加 284 * @og.rev 6.7.3.0 (2017/01/27) tipsClms 追加 285 * @og.rev 6.7.8.0 (2017/04/21) valueMapParam関連 286 * @og.rev 6.9.2.0 (2018/03/05) reqAttUpClms 追加 287 */ 288 @Override 289 protected void release2() { 290 super.release2(); 291 table = null; 292 tableId = HybsSystem.TBL_MDL_KEY; 293 selectedAll = true; 294 keys = null; 295 valClm = null; // 6.7.2.0 (2017/01/16) 新規作成 296 nnClms = null; // 6.7.2.0 (2017/01/16) 名称変更 297 holdTag = null; 298 clsClms = null; // 6.7.3.0 (2017/01/27) 追加 299 tipsClms = null; // 6.7.2.0 (2017/01/16) 名称変更 300 reqAttUpClms= null; // 6.9.2.0 (2018/03/05) request.getAttribute() をセットすると同時に設定するカラム名 301 reqAttClms = null; // 6.9.2.0 (2018/03/05) reqAttUpClms を、配列に分解したもの 302 scope = "session"; // DBTableModel の取得先のscope 303 separator = "_"; 304 xssCheck = HybsSystem.sysBool( "USE_XSS_CHECK" ); // 5.1.7.0 (2010/06/01) XSS解除対応 305 body = null; 306 mapObj.clear(); 307 308 clsClmsNo = null; // clsClmsが指定されない場合は、長さゼロの配列 309 tipsClmsNo = null; // 6.7.3.0 (2017/01/27) tipsClmsが指定されない場合は、長さゼロの配列 310 reqAttClmsNo= null; // 6.9.2.0 (2018/03/05) reqAttUpClmsが指定されない場合は、長さゼロの配列 311 valClmNo = 1; // valClmが指定されない場合は、2番目のカラム(=1)の値を使用します。 312 313 paramMap.clear(); // 6.7.8.0 (2017/04/21) valueMapParam関連 314 restMap.clear(); // 6.7.8.0 (2017/04/21) valueMapParam関連 315 restChangeKey = null ; // ValueMapParamTag で置き換え処理を行うキーワード 316 useNoneClsKey = false ; // mapObj の残り処理をおこなうかどうか(true:行う) 317 } 318 319 /** 320 * 指定のスコープの内部キャッシュ情報に、DBTableModel の選択された値を登録します。 321 * 322 * @og.rev 6.7.1.0 (2017/01/05) 新規作成 323 * @og.rev 6.7.2.0 (2017/01/16) valClm 追加 324 * @og.rev 6.7.3.0 (2017/01/27) tipsClms 追加 325 * @og.rev 6.7.8.0 (2017/04/21) valueMapParam関連 326 * @og.rev 6.9.2.0 (2018/03/05) reqAttUpClms 追加 327 * 328 * @param table DBTableModelオブジェクト 329 */ 330 private void makeMapObj( final DBTableModel table ) { 331 final int[] rowNo = getParameterRows(); 332 if( rowNo.length == 0 ) { return; } 333 334 final int[] keysNo = getClmNos( table,keys , 0 ); // keysが指定されない場合は、先頭カラムを使用します。 335 final int[] nnClmsNo = getClmNos( table,nnClms ,-1 ); // nnClmsが指定されない場合は、長さゼロの配列 336 clsClmsNo = getClmNos( table,clsClms ,-1 ); // clsClmsが指定されない場合は、長さゼロの配列 337 tipsClmsNo = getClmNos( table,tipsClms,-1 ); // tipsClmsが指定されない場合は、長さゼロの配列 338 reqAttClmsNo= getClmNos( table,reqAttUpClms,-1 ); // 6.9.2.0 (2018/03/05) reqAttClmsが指定されない場合は、長さゼロの配列 339 340 if( reqAttUpClms != null && !reqAttUpClms.isEmpty() ) { // 6.9.2.0 (2018/03/05) reqAttUpClms を、配列に分解したもの 341 reqAttClms = reqAttUpClms.split( "," ); 342 } 343 344 for( int j=0; j<rowNo.length; j++ ) { 345 final String[] rowData = table.getValues( j ); 346 347 // まず、nullチェックして、対象行かどうかを判定する。 348 if( isNotNullCheck( rowData , nnClmsNo ) ) { 349 // Map に登録するキーを連結して作成します。 350 final String mapkey = getAppendKeys( rowData , keysNo , separator ); 351 mapObj.computeIfAbsent( mapkey, k -> rowData ); // まだ値に関連付けられていない場合、追加します。(先に登録したデータが有効) 352 // mapObj.put( mapkey, rowData ); // 後で登録したデータが、有効になります。 353 } 354 } 355 restMap.putAll( mapObj ); // 6.7.8.0 (2017/04/21) 一旦、すべてのMapをコピーします。 356 357 // valClmが指定されない場合は、2番目のカラム(=1)の値を使用します。 358 valClmNo = valClm == null || valClm.isEmpty() ? 1 : table.getColumnNo( valClm.trim() ); // 存在しない場合は、Exception 359 } 360 361 /** 362 * カラム名のCSV文字列を、DBTableModel の列番号の配列に変換します。 363 * 364 * カラム名のCSV文字列が、無指定の場合、no で指定するカラム番号を 365 * デフォルトとして使用します。no が、マイナスの場合は、長さゼロの 366 * 配列を返します。 367 * 368 * @og.rev 6.7.1.0 (2017/01/05) 新規作成 369 * @og.rev 6.7.2.0 (2017/01/16) カラム番号の取り方を変更 370 * 371 * @param table DBTableModelオブジェクト 372 * @param clms カラム名のCSV文字列( nullではない ) 373 * @param no clmsが、nullか、空文字の場合の、カラム番号 374 * @return カラム名の列番号の配列 375 */ 376 private int[] getClmNos( final DBTableModel table , final String clms , final int no ) { 377 final int[] clmNo ; 378 if( clms == null || clms.isEmpty() ) { 379 if( no < 0 ) { clmNo = new int[0]; } // 長さゼロの配列 380 else { clmNo = new int[] { no }; } // 指定のカラム番号を持つ配列。 381 } 382 else { 383 final String[] clmAry = clms.split( "," ); 384 clmNo = new int[clmAry.length]; 385 for( int i=0; i<clmAry.length; i++ ) { 386 clmNo[i] = table.getColumnNo( clmAry[i].trim() ); // 存在しない場合は、Exception 387 } 388 } 389 390 return clmNo; 391 } 392 393 /** 394 * 指定のカラムの値のすべてが、nullか、空文字列でない場合は、true を返します。 395 * 396 * @og.rev 6.7.1.0 (2017/01/05) 新規作成 397 * 398 * @param rowData 行データ 399 * @param clmNo カラム番号配列 400 * @return nullか、空文字列でない場合は、true 401 */ 402 private boolean isNotNullCheck( final String[] rowData , final int[] clmNo ) { 403 boolean rtn = true; // カラムがない場合は、true になります。 404 405 // 7.2.9.4 (2020/11/20) PMD:This for loop can be replaced by a foreach loop 406 for( final int clm : clmNo ) { 407 final String val = rowData[ clm ]; 408// for( int i=0; i<clmNo.length; i++ ) { 409// final String val = rowData[ clmNo[i] ]; 410 if( val == null || val.isEmpty() ) { 411 rtn = false; 412 break; 413 } 414 } 415 return rtn; 416 } 417 418 /** 419 * Mapのキーとなるキーカラムの値を連結した値を返します。 420 * 421 * @param rowData 行データ 422 * @param clmNo カラム番号配列 423 * @param sep 結合させる文字列 424 * 425 * @return Mapのキーとなるキーカラムの値を連結した値 426 * @og.rtnNotNull 427 */ 428 private String getAppendKeys( final String[] rowData , final int[] clmNo , final String sep ) { 429 final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE ); 430 431 if( clmNo.length > 0 ) { 432 buf.append( rowData[ clmNo[0] ] ); // 最初のひとつ目 433 for( int i=1; i<clmNo.length; i++ ) { 434 final String val = rowData[ clmNo[i] ]; 435 if( val != null && !val.isEmpty() ) { 436 buf.append( sep ).append( val ); 437 } 438 } 439 } 440 return buf.toString().trim(); 441 } 442 443 /** 444 * Mapの値となる値カラムに対応する文字列配列を返します。 445 * 446 * ここでは、行データに対して、配列の添え字(カラム番号)を元に、値を求めます。 447 * その際、holdTag や、clsClms で指定したクラス名などの付加情報もセットします。 448 * さらに、{@$XXXX} などの、holdTagの抑止(生データを返す) 処理を行います。 449 * 450 * @param rowData 行の配列データ 451 * @param val 値データ 452 * @param isNormal holdTagを使用せず、ノーマル状態の値を出力するかどうか[true:ノーマルの値] 453 * @param cls clsClmsNoの使用を抑止し、指定の値を、class属性にセットします。(nullはclsClmsNoを使用、isEmpty() は、classの削除、それ以外は置き換え) 454 * @param tips tipsClmsNoの使用を抑止し、指定の値を、title属性にセットします。(nullはtipsClmsNoを使用、isEmpty() は、titleの削除、それ以外は置き換え) 455 * @param sufix キーのあいまい指定時に、あいまいキー以降の文字列を指定します。あれば、その値を使用します。 456 * 457 * @og.rev 6.7.3.0 (2017/01/27) tips 追加 458 * 459 * @return Mapのキーに対応する修飾した値 460 * @og.rtnNotNull 461 */ 462 private String getMapVals( final String[] rowData , final String val , final boolean isNormal , final String cls , final String tips , final String sufix ) { 463 String rtnVal = sufix == null || sufix.isEmpty() ? val : sufix ; 464 465 if( !isNormal && holdTag != null && !holdTag.isEmpty() ) { 466 // 毎行ごとに、class属性の値は異なる。 467 final String clazz = cls == null ? getAppendKeys( rowData,clsClmsNo ," " ) : cls ; // class 属性は、スペースで連結 468 final String title = tips == null ? getAppendKeys( rowData,tipsClmsNo," " ) : tips ; // title 属性は、スペースで連結 469 470 final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE ); 471 buf.append( '<' ).append( holdTag ); 472 if( !clazz.isEmpty() ) { buf.append( " class=\"" ).append( clazz ).append( '"' ); } 473 if( !title.isEmpty() ) { buf.append( " title=\"" ).append( title ).append( '"' ); } 474 buf.append( '>' ).append( rtnVal ).append( "</" ).append( holdTag ).append( '>' ); 475 476 rtnVal = buf.toString(); 477 } 478 return rtnVal ; 479 } 480 481 /** 482 * リクエスト情報の文字列を取得します。 483 * 484 * これは、CommonTagSupportの#getRequestValue( String ) を 485 * オーバーライドして、Mapから、設定値を取得します。 486 * 487 * @og.rev 6.7.1.0 (2017/01/05) 新規作成 488 * @og.rev 6.7.2.0 (2017/01/16) valClm 追加 489 * @og.rev 6.7.3.0 (2017/01/27) tips 追加 490 * @og.rev 6.7.6.1 (2017/03/17) 値データを渡すようにします(isAttVal の追加対応)。 491 * @og.rev 6.7.8.0 (2017/04/21) valueMapParam関連 492 * @og.rev 6.8.0.1 (2017/06/30) str指定のキーワード 493 * @og.rev 6.9.2.0 (2018/03/05) reqAttUpClms 追加 494 * 495 * @param key キー 496 * 497 * @return リクエスト情報の文字列 498 * @see CommonTagSupport#getRequestValue( String ) 499 */ 500 @Override 501 protected String getRequestValue( final String key ) { 502 if( key.equals( restChangeKey ) ) { return makeRestValue(); } // 6.7.8.0 (2017/04/21) 503 504 // {@!XXXX} や、{@*XXXX!*} の場合のキー対応。最初に行う。 505 final char ch1 = key.charAt(0); 506 final boolean isNormal = ch1 == '$' ; // holdTag を使わず、値そのものを出します。 507 final boolean isSufix = ch1 == '*' ; // あいまい検索時に、あいまいで削除された部分文字列を使うかどうか。 508 final boolean isAttVal = ch1 == '^' ; // 値を、request.getAttribute()の値を優先して使用します。 509 510 final StringBuilder keyBuf = new StringBuilder( key.trim() ); 511 512 if( isNormal || isSufix || isAttVal ) { keyBuf.deleteCharAt( 0 ); } // 先頭の文字を削除 513 514 // カラム番号の取得のための分割。存在する場合は、必ず一番最後にします。 515 final int ad1 = keyBuf.lastIndexOf( " " ); // 後ろから検索して、スペースで分割 516 int vcNo = valClmNo; 517 if( ad1 > 0 ) { 518 // 必要かどうかはともかく、NumberFormatException で、判定すると、遅くなる気がする。 519 final char ch = keyBuf.charAt( ad1 + 1 ); // 数字であろう先頭文字 520 if( '0' <= ch && ch <= '9' ) { 521 try { 522 vcNo = Integer.parseInt( keyBuf.substring( ad1 + 1 ) ); 523 keyBuf.setLength( ad1 ); // スペースが残っている可能性がある 524 } 525 catch( final NumberFormatException ex ) { // 数値変換失敗時は、普通のパラメータだった場合。 526 System.err.println( ex.getMessage() ); // 8.0.0.0 (2021/07/31) 527// ; 528 // vcNo = valClmNo; // vcNo は、セットする前にException が発生している。 529 // mapkey = key; // mapkey は、スペースも含むすべてのキーになる。・・・・・ NumberFormatException が先なので、setLength されていない。 530 } 531 } 532 } 533 534 // cls="B" 属性の取得 535 final String cls = getExtParam( keyBuf,CLS_KEY ); // 6.8.0.1 (2017/06/30) 関数化 536 537 // 6.7.3.0 (2017/01/27) tips="YYYY" 属性の取得 538 final String tips = getExtParam( keyBuf,TIPS_KEY ); // 6.8.0.1 (2017/06/30) 関数化 539 540 // 6.8.0.1 (2017/06/30) str指定のキーワード。先に取り除かないと、type 判定時の endsWith が効かない。 541 final String instr = getExtParam( keyBuf,STR_KEY ); 542 543 // 中途半端に、スペースが残っていると厄介なので、削除しておきます。 544 final String mapkey = keyBuf.toString().trim(); 545 546 // type==0 は、オリジナル。それ以外は、キーから取り除く文字数 547 final int type = mapkey.endsWith( "!*" ) ? 2 : mapkey.endsWith( "*" ) ? 1 : 0 ; 548 549 final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE ); 550 if( type == 0 ) { 551 final String[] rowData = mapObj.get( mapkey ); 552 restMap.remove( mapkey ); // 6.7.8.0 (2017/04/21) valueMapParam関連 553 554 if( rowData != null && vcNo < rowData.length ) { 555 // isAttVal == true のときは、RequestAttribute から取り出すが、キーは、大文字になっているので注意。 556 // 6.9.2.0 (2018/03/05) DBTableModel への値のフィードバック 557// final String val = isAttVal ? nval( (String)getRequestAttribute( mapkey.toUpperCase(Locale.JAPAN) ) , rowData[vcNo] ) : rowData[vcNo] ; 558 if( isAttVal ) { 559 // isAttVal == true のときは、RequestAttribute から取り出すが、キーは、大文字になっているので注意。 560 final String attVal = (String)getRequestAttribute( mapkey.toUpperCase(Locale.JAPAN) ); 561 if( attVal != null && !attVal.isEmpty() ) { 562 rowData[vcNo] = attVal; // RequestAttribute をテーブルに戻す。 563 for( int i=0; i<reqAttClmsNo.length; i++ ) { // 未設定の場合は、長さゼロの配列。 564 if( reqAttClmsNo[i] >= 0 ) { 565 final String reqAtt = (String)getRequestAttribute( reqAttClms[i] ); 566 rowData[reqAttClmsNo[i]] = reqAtt; // 同時に戻すカラムの値 567 } 568 } 569 } 570 } 571 572 final String val = rowData[vcNo] ; 573 574 buf.append( getMapVals( rowData , val , isNormal , cls , tips , null ) ); 575 } 576 else { 577 buf.append( super.getRequestValue( key , xssCheck ) ); // 添字も合わせて、上位に問い合わせる。 578 } 579 } 580 else { 581 final String subKey = mapkey.substring( 0,mapkey.length()-type ); // ほんとは、keyBuf で処理したかった。 582 final List<String> list = new ArrayList<>(); 583 for( final Map.Entry<String,String[]> entry : mapObj.entrySet() ) { // {@XXXX}を見つける都度、全Mapをスキャンしているので、非効率 584 final String mapkey2 = entry.getKey(); 585 // 6.8.0.1 (2017/06/30) str指定のキーワード 586 if( mapkey2.startsWith( subKey ) && ( instr == null || mapkey2.contains( instr ) ) ) { 587 final String[] rowData = entry.getValue(); 588 if( rowData != null && vcNo < rowData.length ) { 589 final String sufix = isSufix ? mapkey2.substring( subKey.length() ) : null ; // あいまいキーの残りの文字列 590 // isAttVal == true のときは、RequestAttribute から取り出すが、キーは、大文字になっているので注意。 591 // 6.9.2.0 (2018/03/05) DBTableModel への値のフィードバック 592// final String val = isAttVal ? nval( (String)getRequestAttribute( mapkey2.toUpperCase(Locale.JAPAN) ) , rowData[vcNo] ) : rowData[vcNo] ; 593 if( isAttVal ) { 594 // isAttVal == true のときは、RequestAttribute から取り出すが、キーは、大文字になっているので注意。 595 final String attVal = (String)getRequestAttribute( mapkey.toUpperCase(Locale.JAPAN) ); 596 if( attVal != null && !attVal.isEmpty() ) { 597 rowData[vcNo] = attVal; // RequestAttribute をテーブルに戻す。 598 for( int i=0; i<reqAttClmsNo.length; i++ ) { // 未設定の場合は、長さゼロの配列。 599 if( reqAttClmsNo[i] >= 0 ) { 600 final String reqAtt = (String)getRequestAttribute( reqAttClms[i] ); 601 rowData[reqAttClmsNo[i]] = reqAtt; // 同時に戻すカラムの値 602 } 603 } 604 } 605 } 606 607 final String val = rowData[vcNo] ; 608 609 list.add( getMapVals( rowData , val , isNormal , cls , tips , sufix ) ); 610 restMap.remove( mapkey2 ); // 6.7.8.0 (2017/04/21) valueMapParam関連 611 } 612 } 613 } 614 if( type == 2 ) { Collections.reverse( list ); } // 逆順 615 list.forEach( v -> buf.append( v ) ); 616 } 617 618 return buf.toString(); 619 } 620 621 /** 622 * 指定の文字列バッファから、キーワードのパラメータを取り出します。 623 * 624 * 元の文字列バッファは、そのキーワード部分を削除し、パラメータの値は、RETURNで 625 * 返します。存在しない場合は、null を返します。 626 * 627 * @og.rev 6.7.1.0 (2017/01/05) 新規作成 628 * 629 * @param keyBuf 文字列バッファ 630 * @param key キーワード(cls,tips,str) 631 * @return パラメータ 632 */ 633 private String getExtParam( final StringBuilder keyBuf , final String key ) { 634 // key="XXX" 属性の取得 635 String rtn = null; 636 final int ad2 = keyBuf.lastIndexOf( key ); // = の前後にスペースは入れてはいけない。 637 if( ad2 > 0 ) { 638 final int st = ad2 + key.length() ; 639 // cls="B" や、cls='C' のように、文字列指定されているはずなので、その中身を削除します。 640 final String qot = keyBuf.substring( st,st+1 ); // 1文字取り出す。 641 final int ed = keyBuf.indexOf( qot,st+1 ); // 対になる後ろのクオートの位置を見つける。 642 if( ed >= 0 ) { 643 rtn = keyBuf.substring( st+1 , ed ); // 前後のクオートは、含まない。 644 keyBuf.delete( ad2 , ed+1 ) ; // 間を抜く 645 } 646 else { 647 // 文法間違い。どうするか? 648 System.err.println( "指定の文法が間違っています。key=" + key ); 649 } 650 } 651 652 return rtn; 653 } 654 655 /** 656 * 表示データの HybsSystem.ROW_SEL_KEY を元に、選ばれた 行を処理の対象とします。 657 * 658 * @og.rev 6.7.1.0 (2017/01/05) 新規作成 659 * 660 * @return 選択行の配列 661 * @og.rtnNotNull 662 */ 663 @Override 664 protected int[] getParameterRows() { 665 final int[] rowNo ; 666 if( selectedAll ) { 667 final int rowCnt = table.getRowCount(); 668 rowNo = new int[ rowCnt ]; 669 for( int i=0; i<rowCnt; i++ ) { 670 rowNo[i] = i; 671 } 672 } else { 673 rowNo = super.getParameterRows(); 674 } 675 return rowNo ; 676 } 677 678 /** 679 * ValueMapParamTagで設定された各種パラメータ を受け取ります。 680 * 681 * @og.rev 6.7.8.0 (2017/04/21) ValueMapParamTag のパラメータを追加します。 682 * 683 * @param pMap ValueMapParamTagで設定された各種パラメータ 684 */ 685 protected void setParam( final ConcurrentMap<VMP_KEYS,String> pMap ) { 686 paramMap.putAll( pMap ); // ValueMapParamTag と分けるために、内容をコピーします。 687 688 restChangeKey = paramMap.get( VMP_KEYS.REST_CHANGE_KEY ); 689 } 690 691 /** 692 * ValueMapParamTagで設定された各種パラメータを元に、残カラムを処理します。 693 * 694 * 処理としては、{@XXXX} の XXXX 部分を、valueMap の未使用キーに変換します。 695 * その後、通常のパラメータ処理を行います。 696 * REST_MARK_CLM が指定されている場合は、DBTableModel に対して、マーク処理を行います。 697 * 698 * @og.rev 6.7.8.0 (2017/04/21) ValueMapParamTag のパラメータを追加します。 699 * @og.rev 6.9.9.0 (2018/08/20) YYYYキーワードに置換するグループカラム名 700 * @og.rev 6.9.9.2 (2018/09/18) YYYYキーワードで、@のあるなしを対処しておきます(前方一致の必要性)。 701 * @og.rev 7.4.2.3 (2021/06/09) グループ処理で、未処理データが使用済みになった。 702 * 703 * @return 残カラム処理の結果 704 */ 705 private String makeRestValue() { 706 // 先にDBTableModel に対して、マーク処理を行います。 707 // パラメータ処理を行うと、キーワードによっては、restMap から値が削除されるためです。 708 final String markClm = paramMap.get( VMP_KEYS.REST_MARK_CLM ); 709 final String markVal = paramMap.get( VMP_KEYS.REST_MARK_VAL ); 710 711 if( !restMap.isEmpty() && markClm != null && markVal != null ) { 712 final int clmNo = table.getColumnNo( markClm , false ); // ifの階層が深くなるのが嫌なので、まとめてチェックします。 713 final int[] rowNo = getParameterRows(); 714 if( clmNo >=0 && rowNo.length > 0 ) { 715 final int[] keysNo = getClmNos( table,keys , 0 ); // keysが指定されない場合は、先頭カラムを使用します。 716 717 for( int row=0; row<rowNo.length; row++ ) { 718 final String[] rowData = table.getValues( row ); 719 720 // Map に登録されているキーを連結して作成します。 721 final String mapkey = getAppendKeys( rowData , keysNo , separator ); 722 723 if( restMap.containsKey( mapkey ) ) { // 残っている場合 724 table.setValueAt( markVal , row , clmNo ); 725 } 726 } 727 } 728 } 729 730 final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE ); 731 if( restMap.isEmpty() ) { 732 // restMap の残り処理が必要かどうか。restMap が空で、NONE_CLS_KEY が存在する場合は、残を隠す。 733 useNoneClsKey = paramMap.containsKey( VMP_KEYS.NONE_CLS_KEY ); 734 } 735 else { 736 final String changeVal = paramMap.get( VMP_KEYS.BODY_VAL ); 737 // パラメータ処理を行うと、キーワードによっては、restMap から値が削除されるためです。 738 final String[] restKeys = restMap.keySet().toArray( new String[restMap.size()] ); 739 740 final String grpClm = paramMap.get( VMP_KEYS.GRP_KEY_CLM ); // 6.9.9.0 (2018/08/20) 741 final int grpClmNo = table.getColumnNo( grpClm , false ); // 6.9.9.0 (2018/08/20) 無ければ、-1 742 743 // 6.9.9.0 (2018/08/20) YYYYキーワードに置換するグループカラム名 対応 744 for( final String key : restKeys ) { 745 final String repStr = changeVal.replaceAll( "XXXX" , key ); 746 747 if( grpClmNo < 0 ) { 748 buf.append( getRequestParameter( repStr ) ); // 従来どおり、YYYY 処理を行わない。 749 } 750 else { 751 final String[] vals = restMap.get( key ); 752 // if( vals == null ) { continue; } // グループ処理で、未処理データが使用済みになった。 753 if( vals == null || vals.length == 0 ) { continue; } // 7.4.2.3 (2021/06/09) グループ処理で、未処理データが使用済みになった。 754 final String grpKey = vals[grpClmNo]; 755 final String repStr2 = repStr.replaceAll( "YYYY" , grpKey ); 756 buf.append( getRequestParameter( repStr2 ) ); 757 } 758 } 759 760// // 6.9.9.0 (2018/08/20) 761// for( final String key : restKeys ) { 762// final String repStr = changeVal.replaceAll( "XXXX" , key ); 763// buf.append( getRequestParameter( repStr ) ); 764// } 765 } 766 767 return buf.toString(); 768 } 769 770 /** 771 * 【TAG】データを全件選択済みとして処理するかどうか[true/false]を指定します(初期値:false)。 772 * 773 * @og.tag 774 * 全てのデータを選択済みデータとして扱って処理します。 775 * 全件処理する場合に、(true/false)を指定します。 776 * 初期値は false です。 777 * 778 * @og.rev 6.7.1.0 (2017/01/05) 新規作成 779 * 780 * @param all 選択済み処理可否 [true:全件選択済み/false:通常] 781 */ 782 public void setSelectedAll( final String all ) { 783 selectedAll = nval( getRequestParameter( all ),selectedAll ); 784 } 785 786 /** 787 * 【TAG】(通常は使いません)結果のDBTableModelを、sessionに登録するときのキーを指定します 788 * (初期値:HybsSystem#TBL_MDL_KEY[={@og.value HybsSystem#TBL_MDL_KEY}])。 789 * 790 * @og.tag 791 * 検索結果より、DBTableModelオブジェクトを作成します。これを、下流のviewタグ等に 792 * 渡す場合に、通常は、session を利用します。その場合の登録キーです。 793 * query タグを同時に実行して、結果を求める場合、同一メモリに配置される為、 794 * この tableId 属性を利用して、メモリ空間を分けます。 795 * (初期値:HybsSystem#TBL_MDL_KEY[={@og.value HybsSystem#TBL_MDL_KEY}])。 796 * 797 * @og.rev 6.7.1.0 (2017/01/05) 新規作成 798 * 799 * @param id テーブルID (sessionに登録する時のID) 800 */ 801 public void setTableId( final String id ) { 802 tableId = nval( getRequestParameter( id ),tableId ); 803 } 804 805 /** 806 * 【TAG】パラメータ に登録するキーをセットします。 807 * 808 * @og.tag keysが指定されない場合は、先頭カラムを使用します。 809 * 810 * @og.rev 6.7.1.0 (2017/01/05) 新規作成 811 * 812 * @param key1 登録キー 813 */ 814 public void setKeys( final String key1 ) { 815 keys = nval( getRequestParameter( key1 ),keys ) ; 816 } 817 818 /** 819 * 【TAG】パラメータ から取り出す値カラムを指定ます。 820 * 821 * @og.tag valClmが指定されない場合は、2番目のカラムを使用します。 822 * 823 * @og.rev 6.7.2.0 (2017/01/16) 新規作成 824 * 825 * @param clm 取り出す値カラム 826 */ 827 public void setValClm( final String clm ) { 828 valClm = nval( getRequestParameter( clm ),valClm ) ; 829 } 830 831 /** 832 * 【TAG】パラメータが NULL の時に、設定しないカラム名を、CSV形式で指定します。 833 * 834 * @og.tag 835 * nnClms属性:この属性で指定された値が、nullの場合、{@XXXX} の解析を行いません。 836 * 正確に言うと、Mapに取り込みません。この場合、先のholdTag属性で指定したタグそのものも 837 * 出力しません。 838 * 839 * @og.rev 6.7.1.0 (2017/01/05) 新規作成 840 * @og.rev 6.7.2.0 (2017/01/16) 名称変更 841 * 842 * @param clms NULL の時に、設定しないカラム名を、CSV形式で指定 843 */ 844 public void setNnClms( final String clms ) { 845 nnClms = nval( getRequestParameter( clms ),nnClms ); 846 } 847 848 /** 849 * 【TAG】値の前後を、挟むタグを指定します。 850 * 851 * @og.tag 852 * holdTag属性:{@XXXX} を、指定のタグで囲います。 853 * 例えば、holdTag="span" とすると、<span class="YYYYの値" >XXXXの値</span> 854 * という文字列を作成します。 855 * clsClms 属性や、{@XXXX cls="B"} を使用する場合は、holdTag 属性の指定が必要です。 856 * 857 * @og.rev 6.7.1.0 (2017/01/05) 新規作成 858 * 859 * @param tag 値の前後を挟むタグ 860 * @see #setClsClms( String ) 861 */ 862 public void setHoldTag( final String tag ) { 863 holdTag = nval( getRequestParameter( tag ),holdTag ); 864 } 865 866 /** 867 * 【TAG】holdTagを使用するとき、そのタグの属性にclass属性を出力する場合のカラム名をCSV形式で指定します。 868 * 869 * @og.tag 870 * clsClms属性:先の指定のタグで囲う場合、そのタグのclass属性を指定できます。 871 * 複数指定した場合は、スペースで、連結します。 872 * 一括指定ではなく、個別に指定する場合は、{@XXXX cls="B"} 構文を使用します。 873 * holdTag属性が設定されていない場合は、どちらも無視されます。 874 * 875 * @og.rev 6.7.1.0 (2017/01/05) 新規作成 876 * @og.rev 6.7.2.0 (2017/01/16) 名称変更 877 * 878 * @param clms class属性を出力する場合のカラム名を、CSV形式で指定 879 * @see #setHoldTag( String ) 880 */ 881 public void setClsClms( final String clms ) { 882 clsClms = nval( getRequestParameter( clms ),clsClms ); 883 } 884 885 /** 886 * 【TAG】holdTagを使用するとき、そのタグの属性にtitle属性を出力する場合のカラム名をCSV形式で指定します。 887 * 888 * @og.tag 889 * tipsClms属性:先の指定のタグで囲う場合、そのタグのtitle属性を指定できます。 890 * 複数指定した場合は、スペースで、連結します。 891 * 一括指定ではなく、個別に指定する場合は、{@XXXX tips="YYYY"} 構文を使用します。 892 * holdTag属性が設定されていない場合は、どちらも無視されます。 893 * 894 * @og.rev 6.7.3.0 (2017/01/16) 名称変更 895 * 896 * @param clms title属性を出力する場合のカラム名を、CSV形式で指定 897 * @see #setHoldTag( String ) 898 */ 899 public void setTipsClms( final String clms ) { 900 tipsClms = nval( getRequestParameter( clms ),tipsClms ); 901 } 902 903 /** 904 * 【TAG】{@^XXXX}使用時に request.getAttribute() をセットすると同時に設定するカラム名をCSV形式で指定します。 905 * 906 * @og.tag 907 * DBTableModel と別に、value等で設定した値を、{@^XXXX} で置き換えますが、 908 * その際、DBTableModel のデータも置き換えないと、表示とデータ(例えば、一覧表示やファイル出力時)が異なります。 909 * また、置き換えるに当たって、他の項目(カラム)も置き換えないと、矛盾が生じる恐れがあります。 910 * そこで、request.getAttribute() をセットする場合に、同時にセットするカラムを指定することで、 911 * 同時に値の書き換えを行います。 912 * なお、値は、request.getAttribute() で取得します。 913 * 914 * @og.rev 6.9.2.0 (2018/03/05) 新規作成 915 * 916 * @param clms request.getAttribute()使用時に、同時に置き換えるカラム名を、CSV形式で指定 917 */ 918 public void setReqAttUpClms( final String clms ) { 919 reqAttUpClms = nval( getRequestParameter( clms ),reqAttUpClms ); 920 } 921 922 /** 923 * 【TAG】キーとなるカラム名の値を連結する項目区切り文字をセットします(初期値:"_")。 924 * 925 * @og.tag 926 * keysで、複数のキーの値を連結して、Mapのキーにしますが、そのときの連結文字列を指定します。 927 * 初期値は、"_" に設定されています。 928 * 929 * @og.rev 6.7.1.0 (2017/01/05) 新規作成 930 * 931 * @param sepa 連結文字列 (初期値:"_") 932 */ 933 public void setSeparator( final String sepa ) { 934 separator = nval( getRequestParameter( sepa ),separator ); 935 } 936 937 /** 938 * 【TAG】パラメータの HTMLTag開始/終了文字(><) 存在チェックを実施するかどうか[true/false]を設定します 939 * (初期値:USE_XSS_CHECK[={@og.value SystemData#USE_XSS_CHECK}])。 940 * 941 * @og.tag 942 * クロスサイトスクリプティング(XSS)対策の一環としてless/greater than signについてのチェックを行います。 943 * (><) が含まれていたエラーにする(true)/かノーチェックか(false)を指定します。 944 * (初期値:システム定数のUSE_XSS_CHECK[={@og.value SystemData#USE_XSS_CHECK}])。 945 * 946 * @og.rev 6.7.1.0 (2017/01/05) 新規作成 947 * 948 * @param flag XSSチェック [true:する/false:しない] 949 * @see org.opengion.hayabusa.common.SystemData#USE_XSS_CHECK 950 */ 951 public void setXssCheck( final String flag ) { 952 xssCheck = nval( getRequestParameter( flag ),xssCheck ); 953 } 954 955 /** 956 * このオブジェクトの文字列表現を返します。 957 * 基本的にデバッグ目的に使用します。 958 * 959 * @og.rev 6.7.1.0 (2017/01/05) 新規作成 960 * 961 * @return このクラスの文字列表現 962 * @og.rtnNotNull 963 */ 964 @Override 965 public String toString() { 966 return ToString.title( this.getClass().getName() ) 967 .println( "VERSION" ,VERSION ) 968 .println( "tableId" ,tableId ) 969 .println( "selectedAll" ,selectedAll ) 970 .println( "keys" ,keys ) 971 .println( "holdTag" ,holdTag ) 972 .println( "clsClms" ,clsClms ) 973 .println( "tipsClms" ,tipsClms ) 974 .println( "valClm" ,valClm ) 975 .println( "nnClms" ,nnClms ) 976 .println( "scope" ,scope ) 977 .println( "separator" ,separator ) 978 .println( "xssCheck" ,xssCheck ) 979 .println( "Other..." ,getAttributes().getAttribute() ) 980 .fixForm().toString() ; 981 } 982}