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