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 = "6.9.9.2 (2018/09/18)" ; 166 private static final long serialVersionUID = 699220180918L ; 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 ; 527 // vcNo = valClmNo; // vcNo は、セットする前にException が発生している。 528 // mapkey = key; // mapkey は、スペースも含むすべてのキーになる。・・・・・ NumberFormatException が先なので、setLength されていない。 529 } 530 } 531 } 532 533 // cls="B" 属性の取得 534 final String cls = getExtParam( keyBuf,CLS_KEY ); // 6.8.0.1 (2017/06/30) 関数化 535 536 // 6.7.3.0 (2017/01/27) tips="YYYY" 属性の取得 537 final String tips = getExtParam( keyBuf,TIPS_KEY ); // 6.8.0.1 (2017/06/30) 関数化 538 539 // 6.8.0.1 (2017/06/30) str指定のキーワード。先に取り除かないと、type 判定時の endsWith が効かない。 540 final String instr = getExtParam( keyBuf,STR_KEY ); 541 542 // 中途半端に、スペースが残っていると厄介なので、削除しておきます。 543 final String mapkey = keyBuf.toString().trim(); 544 545 // type==0 は、オリジナル。それ以外は、キーから取り除く文字数 546 final int type = mapkey.endsWith( "!*" ) ? 2 : mapkey.endsWith( "*" ) ? 1 : 0 ; 547 548 final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE ); 549 if( type == 0 ) { 550 final String[] rowData = mapObj.get( mapkey ); 551 restMap.remove( mapkey ); // 6.7.8.0 (2017/04/21) valueMapParam関連 552 553 if( rowData != null && vcNo < rowData.length ) { 554 // isAttVal == true のときは、RequestAttribute から取り出すが、キーは、大文字になっているので注意。 555 // 6.9.2.0 (2018/03/05) DBTableModel への値のフィードバック 556// final String val = isAttVal ? nval( (String)getRequestAttribute( mapkey.toUpperCase(Locale.JAPAN) ) , rowData[vcNo] ) : rowData[vcNo] ; 557 if( isAttVal ) { 558 // isAttVal == true のときは、RequestAttribute から取り出すが、キーは、大文字になっているので注意。 559 final String attVal = (String)getRequestAttribute( mapkey.toUpperCase(Locale.JAPAN) ); 560 if( attVal != null && !attVal.isEmpty() ) { 561 rowData[vcNo] = attVal; // RequestAttribute をテーブルに戻す。 562 for( int i=0; i<reqAttClmsNo.length; i++ ) { // 未設定の場合は、長さゼロの配列。 563 if( reqAttClmsNo[i] >= 0 ) { 564 final String reqAtt = (String)getRequestAttribute( reqAttClms[i] ); 565 rowData[reqAttClmsNo[i]] = reqAtt; // 同時に戻すカラムの値 566 } 567 } 568 } 569 } 570 571 final String val = rowData[vcNo] ; 572 573 buf.append( getMapVals( rowData , val , isNormal , cls , tips , null ) ); 574 } 575 else { 576 buf.append( super.getRequestValue( key , xssCheck ) ); // 添字も合わせて、上位に問い合わせる。 577 } 578 } 579 else { 580 final String subKey = mapkey.substring( 0,mapkey.length()-type ); // ほんとは、keyBuf で処理したかった。 581 final List<String> list = new ArrayList<>(); 582 for( final Map.Entry<String,String[]> entry : mapObj.entrySet() ) { // {@XXXX}を見つける都度、全Mapをスキャンしているので、非効率 583 final String mapkey2 = entry.getKey(); 584 // 6.8.0.1 (2017/06/30) str指定のキーワード 585 if( mapkey2.startsWith( subKey ) && ( instr == null || mapkey2.contains( instr ) ) ) { 586 final String[] rowData = entry.getValue(); 587 if( rowData != null && vcNo < rowData.length ) { 588 final String sufix = isSufix ? mapkey2.substring( subKey.length() ) : null ; // あいまいキーの残りの文字列 589 // isAttVal == true のときは、RequestAttribute から取り出すが、キーは、大文字になっているので注意。 590 // 6.9.2.0 (2018/03/05) DBTableModel への値のフィードバック 591// final String val = isAttVal ? nval( (String)getRequestAttribute( mapkey2.toUpperCase(Locale.JAPAN) ) , rowData[vcNo] ) : rowData[vcNo] ; 592 if( isAttVal ) { 593 // isAttVal == true のときは、RequestAttribute から取り出すが、キーは、大文字になっているので注意。 594 final String attVal = (String)getRequestAttribute( mapkey.toUpperCase(Locale.JAPAN) ); 595 if( attVal != null && !attVal.isEmpty() ) { 596 rowData[vcNo] = attVal; // RequestAttribute をテーブルに戻す。 597 for( int i=0; i<reqAttClmsNo.length; i++ ) { // 未設定の場合は、長さゼロの配列。 598 if( reqAttClmsNo[i] >= 0 ) { 599 final String reqAtt = (String)getRequestAttribute( reqAttClms[i] ); 600 rowData[reqAttClmsNo[i]] = reqAtt; // 同時に戻すカラムの値 601 } 602 } 603 } 604 } 605 606 final String val = rowData[vcNo] ; 607 608 list.add( getMapVals( rowData , val , isNormal , cls , tips , sufix ) ); 609 restMap.remove( mapkey2 ); // 6.7.8.0 (2017/04/21) valueMapParam関連 610 } 611 } 612 } 613 if( type == 2 ) { Collections.reverse( list ); } // 逆順 614 list.forEach( v -> buf.append( v ) ); 615 } 616 617 return buf.toString(); 618 } 619 620 /** 621 * 指定の文字列バッファから、キーワードのパラメータを取り出します。 622 * 623 * 元の文字列バッファは、そのキーワード部分を削除し、パラメータの値は、RETURNで 624 * 返します。存在しない場合は、null を返します。 625 * 626 * @og.rev 6.7.1.0 (2017/01/05) 新規作成 627 * 628 * @param keyBuf 文字列バッファ 629 * @param key キーワード(cls,tips,str) 630 * @return パラメータ 631 */ 632 private String getExtParam( final StringBuilder keyBuf , final String key ) { 633 // key="XXX" 属性の取得 634 String rtn = null; 635 final int ad2 = keyBuf.lastIndexOf( key ); // = の前後にスペースは入れてはいけない。 636 if( ad2 > 0 ) { 637 final int st = ad2 + key.length() ; 638 // cls="B" や、cls='C' のように、文字列指定されているはずなので、その中身を削除します。 639 final String qot = keyBuf.substring( st,st+1 ); // 1文字取り出す。 640 final int ed = keyBuf.indexOf( qot,st+1 ); // 対になる後ろのクオートの位置を見つける。 641 if( ed >= 0 ) { 642 rtn = keyBuf.substring( st+1 , ed ); // 前後のクオートは、含まない。 643 keyBuf.delete( ad2 , ed+1 ) ; // 間を抜く 644 } 645 else { 646 // 文法間違い。どうするか? 647 System.err.println( "指定の文法が間違っています。key=" + key ); 648 } 649 } 650 651 return rtn; 652 } 653 654 /** 655 * 表示データの HybsSystem.ROW_SEL_KEY を元に、選ばれた 行を処理の対象とします。 656 * 657 * @og.rev 6.7.1.0 (2017/01/05) 新規作成 658 * 659 * @return 選択行の配列 660 * @og.rtnNotNull 661 */ 662 @Override 663 protected int[] getParameterRows() { 664 final int[] rowNo ; 665 if( selectedAll ) { 666 final int rowCnt = table.getRowCount(); 667 rowNo = new int[ rowCnt ]; 668 for( int i=0; i<rowCnt; i++ ) { 669 rowNo[i] = i; 670 } 671 } else { 672 rowNo = super.getParameterRows(); 673 } 674 return rowNo ; 675 } 676 677 /** 678 * ValueMapParamTagで設定された各種パラメータ を受け取ります。 679 * 680 * @og.rev 6.7.8.0 (2017/04/21) ValueMapParamTag のパラメータを追加します。 681 * 682 * @param pMap ValueMapParamTagで設定された各種パラメータ 683 */ 684 protected void setParam( final ConcurrentMap<VMP_KEYS,String> pMap ) { 685 paramMap.putAll( pMap ); // ValueMapParamTag と分けるために、内容をコピーします。 686 687 restChangeKey = paramMap.get( VMP_KEYS.REST_CHANGE_KEY ); 688 } 689 690 /** 691 * ValueMapParamTagで設定された各種パラメータを元に、残カラムを処理します。 692 * 693 * 処理としては、{@XXXX} の XXXX 部分を、valueMap の未使用キーに変換します。 694 * その後、通常のパラメータ処理を行います。 695 * REST_MARK_CLM が指定されている場合は、DBTableModel に対して、マーク処理を行います。 696 * 697 * @og.rev 6.7.8.0 (2017/04/21) ValueMapParamTag のパラメータを追加します。 698 * @og.rev 6.9.9.0 (2018/08/20) YYYYキーワードに置換するグループカラム名 699 * @og.rev 6.9.9.2 (2018/09/18) YYYYキーワードで、@のあるなしを対処しておきます(前方一致の必要性)。 700 * 701 * @return 残カラム処理の結果 702 */ 703 private String makeRestValue() { 704 // 先にDBTableModel に対して、マーク処理を行います。 705 // パラメータ処理を行うと、キーワードによっては、restMap から値が削除されるためです。 706 final String markClm = paramMap.get( VMP_KEYS.REST_MARK_CLM ); 707 final String markVal = paramMap.get( VMP_KEYS.REST_MARK_VAL ); 708 if( !restMap.isEmpty() && markClm != null && markVal != null ) { 709 final int clmNo = table.getColumnNo( markClm , false ); // ifの階層が深くなるのが嫌なので、まとめてチェックします。 710 final int[] rowNo = getParameterRows(); 711 if( clmNo >=0 && rowNo.length > 0 ) { 712 final int[] keysNo = getClmNos( table,keys , 0 ); // keysが指定されない場合は、先頭カラムを使用します。 713 714 for( int row=0; row<rowNo.length; row++ ) { 715 final String[] rowData = table.getValues( row ); 716 717 // Map に登録されているキーを連結して作成します。 718 final String mapkey = getAppendKeys( rowData , keysNo , separator ); 719 720 if( restMap.containsKey( mapkey ) ) { // 残っている場合 721 table.setValueAt( markVal , row , clmNo ); 722 } 723 } 724 } 725 } 726 727 final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE ); 728 if( restMap.isEmpty() ) { 729 // restMap の残り処理が必要かどうか。restMap が空で、NONE_CLS_KEY が存在する場合は、残を隠す。 730 useNoneClsKey = paramMap.containsKey( VMP_KEYS.NONE_CLS_KEY ); 731 } 732 else { 733 final String changeVal = paramMap.get( VMP_KEYS.BODY_VAL ); 734 // パラメータ処理を行うと、キーワードによっては、restMap から値が削除されるためです。 735 final String[] restKeys = restMap.keySet().toArray( new String[restMap.size()] ); 736 737 final String grpClm = paramMap.get( VMP_KEYS.GRP_KEY_CLM ); // 6.9.9.0 (2018/08/20) 738 final int grpClmNo = table.getColumnNo( grpClm , false ); // 6.9.9.0 (2018/08/20) 無ければ、-1 739 740 // 6.9.9.0 (2018/08/20) YYYYキーワードに置換するグループカラム名 対応 741 for( final String key : restKeys ) { 742 final String repStr = changeVal.replaceAll( "XXXX" , key ); 743 744 if( grpClmNo < 0 ) { 745 buf.append( getRequestParameter( repStr ) ); // 従来どおり、YYYY 処理を行わない。 746 } 747 else { 748 final String[] vals = restMap.get( key ); 749 if( vals == null ) { continue; } // グループ処理で、未処理データが使用済みになった。 750 final String grpKey = vals[grpClmNo]; 751 final String repStr2 = repStr.replaceAll( "YYYY" , grpKey ); 752 753 buf.append( getRequestParameter( repStr2 ) ); 754 } 755 } 756 757// // 6.9.9.0 (2018/08/20) 758// for( final String key : restKeys ) { 759// final String repStr = changeVal.replaceAll( "XXXX" , key ); 760// buf.append( getRequestParameter( repStr ) ); 761// } 762 } 763 764 return buf.toString(); 765 } 766 767 /** 768 * 【TAG】データを全件選択済みとして処理するかどうか[true/false]を指定します(初期値:false)。 769 * 770 * @og.tag 771 * 全てのデータを選択済みデータとして扱って処理します。 772 * 全件処理する場合に、(true/false)を指定します。 773 * 初期値は false です。 774 * 775 * @og.rev 6.7.1.0 (2017/01/05) 新規作成 776 * 777 * @param all 選択済み処理可否 [true:全件選択済み/false:通常] 778 */ 779 public void setSelectedAll( final String all ) { 780 selectedAll = nval( getRequestParameter( all ),selectedAll ); 781 } 782 783 /** 784 * 【TAG】(通常は使いません)結果のDBTableModelを、sessionに登録するときのキーを指定します 785 * (初期値:HybsSystem#TBL_MDL_KEY[={@og.value HybsSystem#TBL_MDL_KEY}])。 786 * 787 * @og.tag 788 * 検索結果より、DBTableModelオブジェクトを作成します。これを、下流のviewタグ等に 789 * 渡す場合に、通常は、session を利用します。その場合の登録キーです。 790 * query タグを同時に実行して、結果を求める場合、同一メモリに配置される為、 791 * この tableId 属性を利用して、メモリ空間を分けます。 792 * (初期値:HybsSystem#TBL_MDL_KEY[={@og.value HybsSystem#TBL_MDL_KEY}])。 793 * 794 * @og.rev 6.7.1.0 (2017/01/05) 新規作成 795 * 796 * @param id テーブルID (sessionに登録する時のID) 797 */ 798 public void setTableId( final String id ) { 799 tableId = nval( getRequestParameter( id ),tableId ); 800 } 801 802 /** 803 * 【TAG】パラメータ に登録するキーをセットします。 804 * 805 * @og.tag keysが指定されない場合は、先頭カラムを使用します。 806 * 807 * @og.rev 6.7.1.0 (2017/01/05) 新規作成 808 * 809 * @param key1 登録キー 810 */ 811 public void setKeys( final String key1 ) { 812 keys = nval( getRequestParameter( key1 ),keys ) ; 813 } 814 815 /** 816 * 【TAG】パラメータ から取り出す値カラムを指定ます。 817 * 818 * @og.tag valClmが指定されない場合は、2番目のカラムを使用します。 819 * 820 * @og.rev 6.7.2.0 (2017/01/16) 新規作成 821 * 822 * @param clm 取り出す値カラム 823 */ 824 public void setValClm( final String clm ) { 825 valClm = nval( getRequestParameter( clm ),valClm ) ; 826 } 827 828 /** 829 * 【TAG】パラメータが NULL の時に、設定しないカラム名を、CSV形式で指定します。 830 * 831 * @og.tag 832 * nnClms属性:この属性で指定された値が、nullの場合、{@XXXX} の解析を行いません。 833 * 正確に言うと、Mapに取り込みません。この場合、先のholdTag属性で指定したタグそのものも 834 * 出力しません。 835 * 836 * @og.rev 6.7.1.0 (2017/01/05) 新規作成 837 * @og.rev 6.7.2.0 (2017/01/16) 名称変更 838 * 839 * @param clms NULL の時に、設定しないカラム名を、CSV形式で指定 840 */ 841 public void setNnClms( final String clms ) { 842 nnClms = nval( getRequestParameter( clms ),nnClms ); 843 } 844 845 /** 846 * 【TAG】値の前後を、挟むタグを指定します。 847 * 848 * @og.tag 849 * holdTag属性:{@XXXX} を、指定のタグで囲います。 850 * 例えば、holdTag="span" とすると、<span class="YYYYの値" >XXXXの値</span> 851 * という文字列を作成します。 852 * clsClms 属性や、{@XXXX cls="B"} を使用する場合は、holdTag 属性の指定が必要です。 853 * 854 * @og.rev 6.7.1.0 (2017/01/05) 新規作成 855 * 856 * @param tag 値の前後を挟むタグ 857 * @see #setClsClms( String ) 858 */ 859 public void setHoldTag( final String tag ) { 860 holdTag = nval( getRequestParameter( tag ),holdTag ); 861 } 862 863 /** 864 * 【TAG】holdTagを使用するとき、そのタグの属性にclass属性を出力する場合のカラム名をCSV形式で指定します。 865 * 866 * @og.tag 867 * clsClms属性:先の指定のタグで囲う場合、そのタグのclass属性を指定できます。 868 * 複数指定した場合は、スペースで、連結します。 869 * 一括指定ではなく、個別に指定する場合は、{@XXXX cls="B"} 構文を使用します。 870 * holdTag属性が設定されていない場合は、どちらも無視されます。 871 * 872 * @og.rev 6.7.1.0 (2017/01/05) 新規作成 873 * @og.rev 6.7.2.0 (2017/01/16) 名称変更 874 * 875 * @param clms class属性を出力する場合のカラム名を、CSV形式で指定 876 * @see #setHoldTag( String ) 877 */ 878 public void setClsClms( final String clms ) { 879 clsClms = nval( getRequestParameter( clms ),clsClms ); 880 } 881 882 /** 883 * 【TAG】holdTagを使用するとき、そのタグの属性にtitle属性を出力する場合のカラム名をCSV形式で指定します。 884 * 885 * @og.tag 886 * tipsClms属性:先の指定のタグで囲う場合、そのタグのtitle属性を指定できます。 887 * 複数指定した場合は、スペースで、連結します。 888 * 一括指定ではなく、個別に指定する場合は、{@XXXX tips="YYYY"} 構文を使用します。 889 * holdTag属性が設定されていない場合は、どちらも無視されます。 890 * 891 * @og.rev 6.7.3.0 (2017/01/16) 名称変更 892 * 893 * @param clms title属性を出力する場合のカラム名を、CSV形式で指定 894 * @see #setHoldTag( String ) 895 */ 896 public void setTipsClms( final String clms ) { 897 tipsClms = nval( getRequestParameter( clms ),tipsClms ); 898 } 899 900 /** 901 * 【TAG】{@^XXXX}使用時に request.getAttribute() をセットすると同時に設定するカラム名をCSV形式で指定します。 902 * 903 * @og.tag 904 * DBTableModel と別に、value等で設定した値を、{@^XXXX} で置き換えますが、 905 * その際、DBTableModel のデータも置き換えないと、表示とデータ(例えば、一覧表示やファイル出力時)が異なります。 906 * また、置き換えるに当たって、他の項目(カラム)も置き換えないと、矛盾が生じる恐れがあります。 907 * そこで、request.getAttribute() をセットする場合に、同時にセットするカラムを指定することで、 908 * 同時に値の書き換えを行います。 909 * なお、値は、request.getAttribute() で取得します。 910 * 911 * @og.rev 6.9.2.0 (2018/03/05) 新規作成 912 * 913 * @param clms request.getAttribute()使用時に、同時に置き換えるカラム名を、CSV形式で指定 914 */ 915 public void setReqAttUpClms( final String clms ) { 916 reqAttUpClms = nval( getRequestParameter( clms ),reqAttUpClms ); 917 } 918 919 /** 920 * 【TAG】キーとなるカラム名の値を連結する項目区切り文字をセットします(初期値:"_")。 921 * 922 * @og.tag 923 * keysで、複数のキーの値を連結して、Mapのキーにしますが、そのときの連結文字列を指定します。 924 * 初期値は、"_" に設定されています。 925 * 926 * @og.rev 6.7.1.0 (2017/01/05) 新規作成 927 * 928 * @param sepa 連結文字列 (初期値:"_") 929 */ 930 public void setSeparator( final String sepa ) { 931 separator = nval( getRequestParameter( sepa ),separator ); 932 } 933 934 /** 935 * 【TAG】パラメータの HTMLTag開始/終了文字(><) 存在チェックを実施するかどうか[true/false]を設定します 936 * (初期値:USE_XSS_CHECK[={@og.value SystemData#USE_XSS_CHECK}])。 937 * 938 * @og.tag 939 * クロスサイトスクリプティング(XSS)対策の一環としてless/greater than signについてのチェックを行います。 940 * (><) が含まれていたエラーにする(true)/かノーチェックか(false)を指定します。 941 * (初期値:システム定数のUSE_XSS_CHECK[={@og.value SystemData#USE_XSS_CHECK}])。 942 * 943 * @og.rev 6.7.1.0 (2017/01/05) 新規作成 944 * 945 * @param flag XSSチェック [true:する/false:しない] 946 * @see org.opengion.hayabusa.common.SystemData#USE_XSS_CHECK 947 */ 948 public void setXssCheck( final String flag ) { 949 xssCheck = nval( getRequestParameter( flag ),xssCheck ); 950 } 951 952 /** 953 * このオブジェクトの文字列表現を返します。 954 * 基本的にデバッグ目的に使用します。 955 * 956 * @og.rev 6.7.1.0 (2017/01/05) 新規作成 957 * 958 * @return このクラスの文字列表現 959 * @og.rtnNotNull 960 */ 961 @Override 962 public String toString() { 963 return ToString.title( this.getClass().getName() ) 964 .println( "VERSION" ,VERSION ) 965 .println( "tableId" ,tableId ) 966 .println( "selectedAll" ,selectedAll ) 967 .println( "keys" ,keys ) 968 .println( "holdTag" ,holdTag ) 969 .println( "clsClms" ,clsClms ) 970 .println( "tipsClms" ,tipsClms ) 971 .println( "valClm" ,valClm ) 972 .println( "nnClms" ,nnClms ) 973 .println( "scope" ,scope ) 974 .println( "separator" ,separator ) 975 .println( "xssCheck" ,xssCheck ) 976 .println( "Other..." ,getAttributes().getAttribute() ) 977 .fixForm().toString() ; 978 } 979}