001/* 002 * Copyright (c) 2009 The openGion Project. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 013 * either express or implied. See the License for the specific language 014 * governing permissions and limitations under the License. 015 */ 016package org.opengion.hayabusa.taglib; 017 018import java.util.ArrayList; 019import java.util.Collections; 020import java.util.Enumeration; 021import java.util.HashMap; 022import java.util.List; 023import java.util.Map; 024import java.util.stream.Collectors; // 6.4.3.4 (2016/03/11) 025 026import org.opengion.fukurou.system.OgBuilder ; // 6.4.4.1 (2016/03/18) 027import org.opengion.fukurou.system.OgRuntimeException ; // 6.4.2.0 (2016/01/29) 028import org.opengion.fukurou.util.StringUtil; 029import org.opengion.fukurou.util.TagBuffer; 030import org.opengion.fukurou.util.ToString; // 6.1.1.0 (2015/01/17) 031import org.opengion.hayabusa.common.HybsSystem; 032import org.opengion.hayabusa.common.HybsSystemException; 033import org.opengion.hayabusa.db.DBColumn; 034import org.opengion.hayabusa.db.DBEditConfig; 035// import org.opengion.hayabusa.db.DBEditConfigManager; // 6.4.5.0 (2016/04/08) 6.9.2.1 (2018/03/12) 廃止 036import org.opengion.hayabusa.db.DBLastSql; 037import org.opengion.hayabusa.db.DBTableModel; 038 039import static org.opengion.fukurou.util.StringUtil.nval; 040 041/** 042 * 画面表示、集計に関する設定情報の表示、登録を行うためのタグです。 043 * (このタグは標準の設定編集画面に組み込んで使用され、各画面JSPから呼び出すことはありません) 044 * 045 * このタグは、ユーザー単位に管理される編集設定オブジェクトに対するI/Fの機能を 046 * 提供しています。この編集設定オブジェクトについては、画面毎に設定を行うため、 047 * タグの呼び出しには、画面IDが必須となっています。 048 * 049 * 具体的な機能としては、3つの機能を提供します。 050 * (1)設定画面表示(command="GET") 051 * ユーザー単位に管理される編集設定オブジェクトをHTMLに変換して表示 052 * また、表示カラムの一覧(CSV形式)については、画面側のJavaScriptで再設定を行うため、 053 * その値を"viewClms"という名前のhiddenタグで出力します。 054 * (2)編集名一覧(command="LIST") 055 * 指定の画面IDに対して、設定されている編集名の一覧をプルダウン(selectタグ)に 056 * 変換して表示します。(name="editName") 057 * (3)設定情報登録/削除(command="SET"/"DELETE") 058 * (1)で設定された内容に対して、編集名を指定してその内容を保存/削除します。 059 * 情報の保存は、command="GET"で表示される項目名と連動していますので、単独での使用は 060 * できません。 061 * 062 * @og.formSample 063 * ●形式:一般ユーザーが直接組み込むことはありません。 064 * ●body:なし 065 * 066 * ●Tag定義: 067 * <og:editConfig 068 * command ○【TAG】command を指定します(必須) 069 * gamenId ○【TAG】画面ID を指定します(必須) 070 * editName 【TAG】編集名 を指定します 071 * orderOnly 【TAG】チェックボックスのリードオンリー化を行います(初期値:false) 072 * debug 【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false) 073 * /> 074 * 075 * ●使用例 076 * <og:editConfig command="{@command}" gamenId="{@GAMENID}" editName="{@editName}" /> 077 * 078 * <og:editConfig 079 * command = command設定 (GET/LIST/SET/REMOVE) 080 * gamenId = "GE0000" 画面ID 081 * [ editName ] = "EDITNAME" 編集名 082 * /> 083 * 084 * @og.group 編集設定 085 * 086 * @og.rev 5.3.6.0 (2011/06/01) 087 * 088 * @version 5.0 089 * @author Hiroki Nakamura 090 * @since JDK6.0, 091 */ 092public class EditConfigTag extends CommonTagSupport { 093 /** このプログラムのVERSION文字列を設定します。 {@value} */ 094 private static final String VERSION = "6.9.2.1 (2018/03/12)" ; 095 private static final long serialVersionUID = 692120180312L ; 096 097 private static final String CAN_EDIT_COMMON = HybsSystem.sys( "EDIT_COMMON_ROLES" ); // 6.4.5.0 (2016/04/08) 098 099 private static final String VIEW_PREFIX = "EDIT_VIEW_"; 100 private static final String SUM_PREFIX = "EDIT_SUM_"; 101 private static final String GROUP_PREFIX = "EDIT_GROUP_"; 102 private static final String SUBTOTAL_PREFIX = "EDIT_SUBTOTAL_"; 103 private static final String TOTAL_PREFIX = "EDIT_TOTAL_"; 104 private static final String ORDERBY_PREFIX = "EDIT_ORDERBY_"; 105 private static final String DESC_PREFIX = "EDIT_DESC_"; 106 private static final String GRANDTOTAL_PREFIX = "EDIT_GRANDTOTAL_"; 107 private static final String COMMON_PREFIX = "EDIT_COMMON_"; 108 private static final String FIRSTTOTAL_PREFIX = "EDIT_FIRSTTOTAL_"; // 6.1.1.0 (2015/01/17) 109 110 private String command ; // GET/LIST/SET/REMOVE 111 private String gamenId ; 112 private String editName ; 113 114 private transient DBTableModel table ; // 5.5.2.4 (2012/05/16) transient 定義追加 115 116 private boolean orderOnly ; // 5.5.5.2 (2012/08/10) 117 118 /** 119 * デフォルトコンストラクター 120 * 121 * @og.rev 6.4.2.0 (2016/01/29) PMD refactoring. Each class should declare at least one constructor. 122 */ 123 public EditConfigTag() { super(); } // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。 124 125 /** 126 * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。 127 * 128 * @og.rev 5.7.1.2 (2013/12/20) msg ⇒ errMsg 変更 129 * @og.rev 6.0.2.4 (2014/10/17) JSP修正時の追加カラム対応 130 * @og.rev 6.4.5.0 (2016/04/08) DBEditConfigのローカル化。 131 * @og.rev 5.9.18.1 (2017/03/24) ADD 編集名の共通判別対応 132 * @og.rev 6.9.2.1 (2018/03/12) DBEditConfigManagerを直接取り出す処理を、廃止します 133 * 134 * @return 後続処理の指示 135 */ 136 @Override 137 public int doEndTag() { 138 debugPrint(); 139 140 final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE ); 141 142 // 6.4.5.0 (2016/04/08) DBEditConfigのローカル化。 143 // 6.9.2.1 (2018/03/12) DBEditConfigManagerを直接取り出す処理を、廃止します 144// final DBEditConfigManager dbConfMgr = getUser().getEditConfigManager(); // 6.4.5.0 (2016/04/08) 145 DBEditConfig config = getUser().getEditConfig( gamenId, editName ); // 6.4.5.0 (2016/04/08) 146 // DBEditConfig config = dbConfMgr.getEditConfig( gamenId, editName ); // 6.4.5.0 (2016/04/08) 147 148 // 編集情報をHTMLに変換して表示します。 149 // 表示に当たって、最後に発行されたQUERYのtableId、scopeをチェックした上で 150 // 表示するかを判断します。 151 if( "GET".equals( command ) ) { 152 final DBLastSql lastSql = (DBLastSql)getSessionAttribute( HybsSystem.DB_LAST_SQL_KEY ); 153 if( lastSql != null ) { 154 // 6.1.1.0 (2015/01/17) PMD Avoid if(x != y) ..; else ..; 155 if( lastSql.isViewEditable() && lastSql.isGuiMatch( gamenId ) ) { 156 setScope( lastSql.getScope() ); 157 table = (DBTableModel)getObject( lastSql.getTableId() ); 158 if( table != null ) { 159 String viewClms = null; 160 if( config == null ) { 161 config = new DBEditConfig(); 162 viewClms = lastSql.getViewClmNames(); 163 } 164 else { 165 // 6.0.2.4 (2014/10/17) JSP修正時の追加カラム対応 166 viewClms = config.getViewClms( lastSql.getOrgClmNames() ); 167 } 168 169 buf.append( makeEditTable( viewClms , config ) ); 170 } 171 } 172 else { 173 // この画面は、項目の並び替えはできません。 174 final String rtn = "<b style=\"font-color:red;\">" + getResource().getLabel( "GEE0003" ) + "</b>"; 175 jspPrint( rtn ); 176 } 177 } 178 } 179 // 編集情報を保存します。 180 else if( "SET".equals( command ) ) { 181 if( editName == null || editName.isEmpty() ) { 182 final String errMsg = "編集名が指定されていません。"; 183 throw new HybsSystemException( errMsg ); // 5.7.1.2 (2013/12/20) msg ⇒ errMsg 変更 184 } 185 // 5.9.18.1 (2017/03/24) ADD 編集名の共通判別対応 186 final String isCommon = getRequest().getParameter( COMMON_PREFIX ); 187 // 共通以外で、頭文字が'*'でない場合 188 if( !"1".equals( isCommon ) && '*' == editName.charAt(0) ){ 189 final String errMsg = "共通以外の場合は、編集名に頭文字に*を使用できません。"; 190 throw new HybsSystemException(errMsg); 191 } 192 // 6.9.2.1 (2018/03/12) DBEditConfigManagerを直接取り出す処理を、廃止します 193// saveEditConfig( dbConfMgr ); // 6.4.5.0 (2016/04/08) 194 saveEditConfig(); // 6.9.2.1 (2018/03/12) 195 } 196 // 編集情報を削除します。 197 else if( "DELETE".equals( command ) ) { 198 if( editName == null || editName.isEmpty() ) { 199 final String errMsg = "編集名が指定されていません。"; 200 throw new HybsSystemException( errMsg ); // 5.7.1.2 (2013/12/20) msg ⇒ errMsg 変更 201 } 202 // 6.9.2.1 (2018/03/12) DBEditConfigManagerを直接取り出す処理を、廃止します 203// if( dbConfMgr != null && config != null ) { 204// deleteEditConfig( dbConfMgr , config ); // 6.4.5.0 (2016/04/08) 205 deleteEditConfig( config ); // 6.9.2.1 (2018/03/12) 206// } 207 } 208 // 指定された画面IDに対する編集情報の一覧(プルダウン)を表示します。 209 else if( "LIST".equals( command ) ) { 210 // 6.1.0.0 (2014/12/26) findBugs: null ではなく長さが0の配列を返す。 211 // 6.9.2.1 (2018/03/12) DBEditConfigManagerを直接取り出す処理を、廃止します 212// final DBEditConfig[] configs = dbConfMgr.getEditConfigs( gamenId ); // 6.4.5.0 (2016/04/08) 213 final DBEditConfig[] configs = getUser().getEditConfigs( gamenId ); // 6.4.5.0 (2016/04/08) 214 if( configs.length > 0 ) { 215 buf.append( getEditSelect( configs ) ).append( CR ); 216 } 217 } 218 219 jspPrint( buf.toString() ); 220 221 return EVAL_PAGE ; 222 } 223 224 /** 225 * タグリブオブジェクトをリリースします。 226 * キャッシュされて再利用されるので、フィールドの初期設定を行います。 227 * 228 * @og.rev 5.5.5.2 (2012/08/10) orderOnly対応 229 * @og.rev 6.4.5.0 (2016/04/08) DBEditConfigのローカル化。 230 */ 231 @Override 232 protected void release2() { 233 super.release2(); 234 command = "GET"; 235 gamenId = null; 236 editName = null; 237 table = null; 238 orderOnly = false; //5.5.5.2 (2012/08/10) 239 } 240 241 /** 242 * 編集情報をHTMLに変換して表示します。 243 * 244 * @og.rev 5.4.2.0 (2011/12/01) 入替え対象のカラム列でのみスクロールが表示されるように対応します。 245 * @og.rev 5.5.5.2 (2012/08/10) orderOnly対応 246 * @og.rev 6.1.1.0 (2015/01/17) 総合計を最初の行に追加するかどうか(FirstTotal)の属性を追加 247 * @og.rev 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs) 248 * @og.rev 6.4.5.0 (2016/04/08) 『6.3.9.0 (2015/11/06) 意味不明の div を削除』の影響でレイアウトが崩れたので、戻します。 249 * @og.rev 6.4.5.0 (2016/04/08) DBEditConfigのローカル化。 250 * 251 * @param viewClms 表示カラム(CSV形式) 252 * @param config DBEditConfigオブジェクト 253 * 254 * @return 編集情報のHTML 255 * @og.rtnNotNull 256 */ 257 private String makeEditTable( final String viewClms , final DBEditConfig config ) { 258 final boolean useSum = getUseSum( viewClms ); 259 final String[] viewGroups = StringUtil.csv2Array( viewClms, '|' ); 260 261 final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE ) 262 .append( "<input type=\"hidden\" name=\"viewClms\" id=\"viewClms\" value=\"" ) 263 .append( viewClms ) 264 .append( "\"/><div /><div style=\"float:left;\">" ) // 6.4.5.0 (2016/04/08) そのdiv がないと、配置が狂うため、復活。 265 .append( makeLabelRow( useSum , config ) ) // 6.4.5.0 (2016/04/08) 266 .append( "</div><div id=\"clmLayer\" style=\"float:left; width:670px; overflow-x:scroll;\">" ); 267 268 for( int i=0; i<viewGroups.length; i++ ) { 269 if( i > 0 ) { 270 buf.append( makeSeparateRow( useSum ) ); 271 } 272 buf.append( "<table class=\"clmGroup\" style=\"float:left;\"><tr>" ); 273 final String[] clms = StringUtil.csv2Array( viewGroups[i] ); 274 for( int j=0; j<clms.length; j++ ) { 275 // 6.1.0.0 (2014/12/26) refactoring : Avoid if(x != y) ..; else ..; 276 final boolean isView = !StringUtil.startsChar( clms[j] , '!' ) ; // 6.4.1.1 (2016/01/16) 1文字 String.startsWith 277 // 6.4.1.1 (2016/01/16) 1文字 String.startsWith と、処理順の入れ替え 278 final String clm = isView ? clms[j] : clms[j].substring( 1 ) ; 279 if( "rowCount".equals( clm ) ) { continue; } 280 // 6.1.0.0 (2014/12/26) refactoring : Avoid if(x != y) ..; else ..; 281 buf.append( makeColumnRow( clm, isView, useSum, config ) ); 282 } 283 buf.append( "</tr></table>" ); 284 } 285 buf.append( "</div>" ); 286 287 // 6.1.1.0 (2015/01/17) useSum==true の場合のみ、表示する。 288 if( useSum ) { 289 // 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs) 290 if( config == null ) { 291 final String errMsg = "DBEditConfigが設定されていません。" ; 292 throw new OgRuntimeException( errMsg ); 293 } 294 295 final String grandTotalLabel = "<b>" + getDBColumn( GRANDTOTAL_PREFIX + "LABEL" ).getLongLabel() + ":</b>"; 296 final String firstTotalLabel = "<b>" + getDBColumn( FIRSTTOTAL_PREFIX + "LABEL" ).getLongLabel() + ":</b>"; // 6.1.1.0 (2015/01/17) 297 buf.append( "<div style=\"clear:both;\"><table>" ) 298 .append( makeCheckbox( GRANDTOTAL_PREFIX, config.useGrandTotal(), "h", grandTotalLabel, orderOnly ) ) // 5.5.5.2 (2012/08/10) 299 .append( makeCheckbox( FIRSTTOTAL_PREFIX, config.useFirstTotal(), "h", firstTotalLabel, orderOnly ) ) // 6.1.1.0 (2015/01/17) 300 .append( "</table></div>" ); 301 } 302 303 return buf.toString(); 304 } 305 306 /** 307 * 編集情報のヘッダー(ラベル行)のHTMLを生成します。 308 * 309 * @og.rev 5.4.2.0 (2011/12/01) 表示項目の全チェック機能を追加 310 * @og.rev 5.5.5.2 (2012/08/10) orderOnly対応 311 * @og.rev 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs) 312 * @og.rev 6.4.5.0 (2016/04/08) 共通ラベルは、共通チェックボックスを使用しないときは消します。 313 * @og.rev 6.4.5.0 (2016/04/08) DBEditConfigのローカル化。 314 * 315 * @param useSum 集計対象のカラム(=NUMBER型)が存在しているか [true:存在/false:存在しない] 316 * @param config DBEditConfigオブジェクト 317 * 318 * @return 編集情報のヘッダー(ラベル行)のHTML 319 * @og.rtnNotNull 320 */ 321 private String makeLabelRow( final boolean useSum , final DBEditConfig config ) { 322 final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE ) 323 .append( "<table><tr><td style=\"margin:0px; padding:0px;\"><table>" ); 324 325 // 6.4.5.0 (2016/04/08) static final String CAN_EDIT_COMMON を使用 326 if( getUser().isAccess( CAN_EDIT_COMMON ) ) { 327 // 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs) 328 if( config == null ) { 329 final String errMsg = "DBEditConfigが設定されていません。" ; 330 throw new OgRuntimeException( errMsg ); 331 } 332 333 final String commonLabel = "<b>" + getDBColumn( COMMON_PREFIX + "LABEL" ).getLongLabel() + ":</b>"; // 6.4.5.0 (2016/04/08) else で使わなくなったので。 334 buf.append( makeCheckbox( COMMON_PREFIX, config.isCommon(), "h", commonLabel, orderOnly ) ); // 5.5.5.2 (2012/08/10) 335 } 336 else { 337 // 6.4.5.0 (2016/04/08) 共通ラベルは、共通チェックボックスを使用しないときは消します。 338 // buf.append( makeLabel( commonLabel ) ); 339 buf.append( makeLabel( "" ) ); 340 } 341 final String viewLabel = "<b>" + getDBColumn( VIEW_PREFIX + "LABEL" ).getLongLabel() + ":</b>"; 342 buf.append( makeCheckbox( "VIEW_ALL_CHECK", true, "h", viewLabel, orderOnly ) ); // 5.5.5.2 (2012/08/10) 343 if( useSum ) { 344 buf.append( makeLabel( SUM_PREFIX + "LABEL" ) ); 345 } 346 347 // 6.4.1.1 (2016/01/16) PMD refactoring. Avoid declaring a variable if it is unreferenced before a possible exit point. 348 final String groupLabel = "<b>" + getDBColumn( GROUP_PREFIX + "LABEL" ).getLongLabel() + "</b>" 349 + "<img id=\"groupBtn\" src=\"" + HybsSystem.sys( "JSP" ) + "/image/ball-green.gif\" />"; 350 buf.append( makeCell ( groupLabel, "h" ) ) 351 .append( makeLabel ( SUBTOTAL_PREFIX + "LABEL" ) ) 352 .append( makeLabel ( TOTAL_PREFIX + "LABEL" ) ) 353 .append( makeLabel ( ORDERBY_PREFIX + "LABEL" ) ) 354 .append( makeLabel ( DESC_PREFIX + "LABEL" ) ) 355 .append( "</table></td></tr></table>" ); 356 return buf.toString(); 357 } 358 359 /** 360 * 編集情報のカラム列のHTMLを生成します。 361 * 362 * @og.rev 5.5.5.2 (2012/08/10) orderOnly対応 363 * @og.rev 5.7.5.2 (2014/04/11) 降順はorderOnlyに関わらず編集可能にする 364 * @og.rev 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs) 365 * @og.rev 6.4.4.1 (2016/03/18) StringBuilderの代わりに、OgBuilderを使用する。 366 * 367 * @param clm カラム 368 * @param isView 表示のチェックボックス [true:初期ON/false:初期OFF] 369 * @param useSum 集計対象のカラム(=NUMBER型)が存在しているか [true:存在/false:存在しない] 370 * @param config 編集設定オブジェクト 371 * 372 * @return 編集情報のカラム列のHTMLを生成します。 373 * @og.rtnNotNull 374 */ 375 private String makeColumnRow( final String clm, final boolean isView, final boolean useSum, final DBEditConfig config ) { 376 // 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs) 377 if( table == null ) { 378 final String errMsg = "DBTableModelが設定されていません。" ; 379 throw new OgRuntimeException( errMsg ); 380 } 381 382 final int clmNo = table.getColumnNo( clm, false ); 383 final DBColumn column = ( clmNo < 0 ? getDBColumn( clm ) : table.getDBColumn( clmNo ) ); 384 385 return new OgBuilder() 386 .append( "<td name=\"" , clm ) 387 .append( "\" class=\"sortItem\" style=\"margin:0px; padding:0px;\">" ) 388 .append( "<table>" ) 389 .append( makeLabel ( column.getLongLabel() ) ) 390 .append( makeCheckbox( VIEW_PREFIX + clm, isView , "0", "", orderOnly ) ) // 5.5.5.2 (2012/08/10) 391 .appendIf( useSum , clm , 392 v -> makeCheckbox( SUM_PREFIX + v, config.isSumClm( v ) , "1", "", orderOnly, isNumberClm( v ) ) ) // 5.5.5.2 (2012/08/10) 393 .append( makeCheckbox( GROUP_PREFIX + clm, config.isGroupClm( clm ) , "0", "", orderOnly ) ) // 5.5.5.2 (2012/08/10) 394 .append( makeCheckbox( SUBTOTAL_PREFIX + clm, config.isSubTotalClm( clm ) , "1", "", orderOnly ) ) // 5.5.5.2 (2012/08/10) 395 .append( makeCheckbox( TOTAL_PREFIX + clm, config.isTotalClm( clm ) , "0", "", orderOnly ) ) // 5.5.5.2 (2012/08/10) 396 .append( makeInput ( ORDERBY_PREFIX + clm, config.getOrder( clm ) , "1", "" ) ) 397 .append( makeCheckbox( DESC_PREFIX + clm, config.isOrderByDesc( clm ) , "0", "", false ) ) // 5.7.5.1 (2014/04/11) 398 .append( "</table></td>" ) 399 .toString(); 400 401 } 402 403 /** 404 * チェックボックスのHTML文字列を生成します。 405 * 生成したHTMLは以下のようになります。 406 * 例)<tr><td class="row_[bgCnt]" ...>[prefix]<input type="checkbox" name="[clm]" ... /></td></tr> 407 * 408 * @param clm カラム 409 * @param checked 初期チェック [true:チェック済み/false:通常] 410 * @param bgCnt ゼブラ指定 [0/1/h] 411 * @param prefix チェックボックスのタグの前に挿入するHTML文字列 412 * @param readonly リードオンリー指定 [true:読取専用/false:読書可] 413 * 414 * @og.rev 5.5.5.2 (2012/08/10) readOnly追加 415 * @og.rev 6.1.1.0 (2015/01/17) 内部構造を見直します。 416 * 417 * @return チェックボックスのHMTL文字列 418 */ 419 private String makeCheckbox( final String clm, final boolean checked, final String bgCnt, final String prefix, final boolean readonly ) { 420 return makeCheckbox( clm, checked, bgCnt, prefix, readonly, true ); 421 } 422 423 /** 424 * チェックボックスのHTML文字列を生成します。 425 * 生成したHTMLは以下のようになります。 426 * 例)<tr><td class="row_[bgCnt]" ...>[prefix]<input type="checkbox" name="[clm]" ... /></td></tr> 427 * 428 * isChbox(チェックボックス生成) を、true に指定すると、チェックボックスのinputタグを生成します。 429 * 430 * @og.rev 5.5.5.2 (2012/08/10) readOnly追加 431 * @og.rev 6.1.1.0 (2015/01/17) 内部構造を見直します。 432 * 433 * @param clm カラム 434 * @param checked 初期チェック [true:チェック済み/false:通常] 435 * @param bgCnt ゼブラ指定 [0/1/h] 436 * @param prefix チェックボックスのタグの前に挿入するHTML文字列(nullは禁止) 437 * @param readonly リードオンリー指定 [true:読取専用/false:読書可] 438 * @param isChbox チェックボックス生成 [true:生成する/false:生成しない] 439 * 440 * @return チェックボックスのHMTL文字列 441 */ 442 private String makeCheckbox( final String clm, final boolean checked, final String bgCnt, final String prefix, final boolean readonly, final boolean isChbox ) { 443 if( isChbox ) { 444 445 // 6.1.1.0 (2015/01/17) TagBufferの連結記述 446 final String tag = new TagBuffer( "input" ) 447 .add( "type" , "checkbox" ) 448 .add( "name" , clm ) 449 .add( "value" , "1" ) 450 .add( "checked" , "checked" , checked ) 451 .add( "disabled", "disabled", readonly ) 452 .makeTag(); 453 454 // 6.1.1.0 (2015/01/17) TagBufferの連結記述 455 final String cell = readonly && checked // 6.1.1.0 (2015/01/17) suffix 処理を変更 456 ? tag + new TagBuffer( "input" ) 457 .add( "type", "hidden" ) 458 .add( "name", clm ) 459 .add( "value", "1" ) 460 .makeTag() 461 : tag ; 462 463 return makeCell( prefix + cell , bgCnt ); // 6.1.1.0 (2015/01/17) prefix に、null は禁止 464 } 465 else { 466 return makeCell( prefix + " ", bgCnt ); // 6.1.1.0 (2015/01/17) prefix に、null は禁止 467 } 468 } 469 470 /** 471 * テキスト入力HTML文字列を生成します。 472 * 生成したHTMLは以下のようになります。 473 * 例)<tr><td class="row_[bgCnt]" ...>[prefix]<input type="text" name="[clm]" ... /></td></tr> 474 * 475 * @param clm カラム 476 * @param value 値 477 * @param bgCnt ゼブラ指定 [0/1/h] 478 * @param prefix チェックボックスのタグの前に挿入するHTML文字列(nullは禁止) 479 * 480 * @return チェックボックスのHMTL文字列 481 */ 482 private String makeInput( final String clm, final String value, final String bgCnt, final String prefix ) { 483 // 6.1.1.0 (2015/01/17) TagBufferの連結記述 484 final String tag = new TagBuffer( "input" ) 485 .add( "type" , "text" ) 486 .add( "name" , clm ) 487 .add( "value" , value ) 488 .add( "style" , "width:10px; font-size:10px;" ) 489 .add( "maxlength" , "2" ) 490 .add( "class" , "S9" ) 491 .makeTag(); 492 493 return makeCell( prefix + tag , bgCnt ); // 6.1.1.0 (2015/01/17) prefix に、null は禁止 494 495 } 496 497 /** 498 * 左右分割されている際の分割列のHTML文字列を生成します。 499 * 500 * @og.rev 6.4.4.1 (2016/03/18) StringBuilderの代わりに、OgBuilderを使用する。 501 * 502 * @param useSum 集計対象のカラム(=NUMBER型)が存在しているか [true:存在している/false:存在していない] 503 * 504 * @return チェックボックスのHMTL文字列 505 * @og.rtnNotNull 506 */ 507 private String makeSeparateRow( final boolean useSum ) { 508 final String ROW_H = makeCell( " ", "h" ) ; 509 510 return new OgBuilder() 511 .append( "<table style=\"float:left;\"><tr><td style=\"margin:0px; padding:0px;\"><table>" ) 512 .append( ROW_H ) // ラベル 513 .append( ROW_H ) // 表示 514 .appendIf( useSum , ROW_H ) // 集計項目 515 .append( ROW_H ) // 集計キー 516 .append( ROW_H ) // 小計キー 517 .append( ROW_H ) // 合計キー 518 .append( ROW_H ) // 表示順 519 .append( ROW_H ) // 昇順・降順 520 .append( "</table></td></tr></table>") 521 .toString(); 522 523 } 524 525 /** 526 * ラベルのHTML文字列を生成します。 527 * 528 * @param clm カラム 529 * 530 * @return ラベルのHTML文字列 531 */ 532 private String makeLabel( final String clm ) { 533 return makeCell( getDBColumn( clm ).getLongLabel(), "h" ); 534 } 535 536 /** 537 * セルのHTML文字列を生成します。 538 * 539 * body 属性は、HTML文字列を指定します。 540 * bgCnt は、背景色のゼブラカラーの指定の為の class 属性で、[0/1/h] が指定できます。 541 * 例えば、"0" を指定した場合は、class="row_0" のように、属性を付与します。 542 * 標準の CSSファイルで設定しているのが、[0/1/h] なだけで、上記 class 属性を 543 * custom.css で設定すれば、どのような文字列でも指定可能です。 544 * 545 * @og.rev 6.1.1.0 (2015/01/17) 内部構造を見直します。 546 * 547 * @param body tdタグ内のHTML文字列 548 * @param bgCnt ゼブラ指定 [0/1/h] 549 * 550 * @return セルのHTML文字列 551 * @og.rtnNotNull 552 */ 553 private String makeCell( final String body, final String bgCnt ) { 554 return "<tr><td align=\"center\" style=\"height:22px;\" class=\"row_" + bgCnt + "\">" + body + "</td></tr>"; 555 } 556 557 /** 558 * この編集設定で集計対象のカラム(=NUMBER型)が存在しているかを返します。 559 * 560 * @param viewClms カラム 561 * 562 * @return 集計対象のカラム(=NUMBER型)が存在しているか 563 */ 564 private boolean getUseSum( final String viewClms ) { 565 if( viewClms == null ) { return false; } 566 567 final String[] clms = StringUtil.csv2Array( viewClms.replace( '|', ',' ) ); 568 for( int j=0; j<clms.length; j++ ) { 569 // 6.1.0.0 (2014/12/26) refactoring : Avoid if(x != y) ..; else ..; 570 final String clm = StringUtil.startsChar( clms[j] , '!' ) ? clms[j].substring( 1 ) : clms[j] ; // 6.4.1.1 (2016/01/16) 1文字 String.startsWith 571 if( isNumberClm( clm ) ) { return true; } // ひとつでも見つかれば、true 572 } 573 return false; 574 } 575 576 /** 577 * 引数のカラムがNUMBER型かどうかをチェックします。 578 * 579 * @og.rev 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs) 580 * @og.rev 6.4.4.2 (2016/04/01) contains 判定を行う新しいメソッドを使用します。 581 * @og.rev 6.4.6.0 (2016/05/27) isNumber , isDate 追加。 582 * 583 * @param clm カラム 584 * 585 * @return NUMBER型かどうか 586 */ 587 private boolean isNumberClm( final String clm ) { 588 if( clm == null ) { return false; } 589 // 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs) 590 if( table == null ) { 591 final String errMsg = "DBTableModelが設定されていません。" ; 592 throw new OgRuntimeException( errMsg ); 593 } 594 595 final int no = table.getColumnNo( clm, false ); 596 if( no >= 0 ) { 597 final DBColumn dbClm = table.getDBColumn( no ); 598 // 6.0.0.1 (2014/04/25) These nested if statements could be combined 599 // 6.4.4.2 (2016/04/01) contains 判定を行う新しいメソッドを使用します。 600 return dbClm != null && dbClm.isNumberType(); 601 } 602 return false; 603 } 604 605 /** 606 * 編集設定情報を保存します。 607 * 608 * @og.rev 6.1.1.0 (2015/01/17) 総合計を最初の行に追加するかどうか(FirstTotal)の属性を追加 609 * @og.rev 6.4.5.0 (2016/04/08) UserInfo のEditConfig関連機能を、DBEditConfigManagerに移植します。 610 * @og.rev 5.9.18.1 (2017/03/24) 共通の編集名対応 611 * @og.rev 6.9.2.1 (2018/03/12) DBEditConfigManagerを直接取り出す処理を、廃止します 612 * 613 */ 614// private void saveEditConfig( final DBEditConfigManager dbConfMgr ) { 615 private void saveEditConfig() { 616 final String viewClms = getRequest().getParameter( "viewClms" ); 617 final String sumClms = getColumns( SUM_PREFIX ); 618 final String groupClms = getColumns( GROUP_PREFIX ); 619 final String subTotalClms = getColumns( SUBTOTAL_PREFIX ); 620 final String totalClms = getColumns( TOTAL_PREFIX ); 621 final String useGrandTotal = getRequest().getParameter( GRANDTOTAL_PREFIX ); 622 final String useFirstTotal = getRequest().getParameter( FIRSTTOTAL_PREFIX ); // 6.1.1.0 (2015/01/17) 623 final String orderByClms = getOrderByColumns(); 624 final String isCommon = getRequest().getParameter( COMMON_PREFIX ); 625 626 // 5.9.18.1 (2017/03/24) ADD 編集名の共通判別対応 627 // 共通で、編集名の頭に「*」が無い場合 628 if("1".equals( isCommon ) && !('*' == editName.charAt( 0 ))){ 629 // 編集名の頭に「*」を付与 630 editName = "*"+editName; 631 } 632 // 編集名をリクエストスコープに設定 633 setRequestAttribute("regEditName", editName); 634 635 final DBEditConfig config 636 = new DBEditConfig( editName, viewClms, sumClms, groupClms 637 , subTotalClms, totalClms, useGrandTotal, useFirstTotal, orderByClms, isCommon ); 638 639 getUser().addEditConfig( gamenId, editName, config ); // 6.4.5.0 (2016/04/08) 暫定的に残す 640 // dbConfMgr.addEditConfig( gamenId, editName, config ); 641 } 642 643 /** 644 * 編集設定情報を削除します。 645 * 646 * ※ org.opengion.hayabusa.resource.UserInfo#deleteEditConfig( String , String )でも 647 * 処理しているが、本来は、UserInfoでは処理しないほうが良いため、 648 * 今回は、こちらで判定して処理します。 649 * 650 * @og.rev 6.4.5.0 (2016/04/08) 共通設定した editName が削除できてしまうため、ロール制御を追加します。 651 * @og.rev 6.4.5.0 (2016/04/08) UserInfo のEditConfig関連機能を、DBEditConfigManagerに移植します。 652 * @og.rev 6.9.2.1 (2018/03/12) DBEditConfigManagerを直接取り出す処理を、廃止します 653 * 654 * @param config DBEditConfigオブジェクト 655 */ 656// private void deleteEditConfig( final DBEditConfigManager dbConfMgr , final DBEditConfig config ) { 657 private void deleteEditConfig( final DBEditConfig config ) { 658 final boolean isCommon = config.isCommon(); 659 // 共通で、かつ、共通設定ロールを持っていない場合は、エラーにします。 660 if( isCommon && !getUser().isAccess( CAN_EDIT_COMMON ) ) { 661 final String errMsg = "共通設定されている編集名を削除する権限がありません。"; 662 throw new HybsSystemException( errMsg ); 663 } 664 else { 665 getUser().deleteEditConfig( gamenId, editName ); // 6.4.5.0 (2016/04/08) 暫定的に残す 666 // dbConfMgr.deleteEditConfig( gamenId, editName ); 667 } 668 } 669 670 /** 671 * パラメーターから引数のプレフィックスをキーに、チェックされたカラム一覧(CSV形式)を返します。 672 * 673 * @param prefixKey 各キーの取得するためのプレフィックス 674 * 675 * @return カラム一覧(CSV形式) 676 * @og.rtnNotNull 677 */ 678 private String getColumns( final String prefixKey ) { 679 final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE ); 680 681 final Enumeration<?> enume = getParameterNames(); 682 while( enume.hasMoreElements() ) { 683 final String key = (String)(enume.nextElement()); 684 if( key.startsWith( prefixKey ) ) { 685 final String val = getRequest().getParameter( key ); 686 if( "1".equals( val ) ) { 687 final String clm = key.substring( prefixKey.length() ); 688 if( buf.length() > 0 ) { buf.append( ',' ); } // 6.0.2.5 (2014/10/31) char を append する。 689 buf.append( clm ); 690 } 691 } 692 } 693 694 return buf.toString(); 695 } 696 697 /** 698 * 表示順のカラム一覧(CSV形式)を返します。 699 * 700 * @og.rev 6.4.3.4 (2016/03/11) CSV形式の文字連結を、stream 経由で行います。 701 * 702 * @return 表示順のカラム一覧(CSV形式) 703 * @og.rtnNotNull 704 */ 705 private String getOrderByColumns() { 706 final Enumeration<?> enume = getParameterNames(); 707 final List<Integer> orderNo = new ArrayList<>(); 708 final Map<Integer,String> odrClmMap = new HashMap<>(); 709 while( enume.hasMoreElements() ) { 710 final String key = (String)(enume.nextElement()); 711 if( key.startsWith( ORDERBY_PREFIX ) ) { 712 final String val = getRequest().getParameter( key ); 713 if( val != null && val.length() > 0 ) { 714 String clm = key.substring( ORDERBY_PREFIX.length() ); 715 final String desc = getRequest().getParameter( DESC_PREFIX + clm ); 716 if( "1".equals( desc ) ) { 717 clm = "!" + clm; 718 } 719 // 数字項目以外が入力された場合は無視 720 Integer odno = null; 721 try { 722 odno = Integer.valueOf( val ); 723 } 724 catch( final NumberFormatException ex ) { 725 continue; 726 } 727 String str = odrClmMap.get( odno ); 728 // 同じ番号の場合でも重ならないように振り直しする。 729 while( str != null ) { 730 odno = Integer.valueOf( odno.intValue() + 1 ); 731 str = odrClmMap.get( odno ); 732 } 733 odrClmMap.put( odno, clm ); 734 orderNo.add( odno ); 735 } 736 } 737 } 738 739 Collections.sort( orderNo ); 740 741 // 6.4.3.4 (2016/03/11) CSV形式の文字連結を、stream 経由で行います。 742 return orderNo.stream() 743 .map( no -> odrClmMap.get( no ) ) 744 .collect( Collectors.joining( "," ) ); 745 746 } 747 748 /** 749 * 編集設定一覧のプルダウンメニューを作成します。 750 * 751 * @param configs DBEditConfig配列(可変長引数) 752 * 753 * @return 編集一覧のプルダウン 754 * @og.rtnNotNull 755 */ 756 private String getEditSelect( final DBEditConfig... configs ) { 757 final DBColumn column = getDBColumn( "editName" ); 758 759 final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE ) 760 .append( "<span class=\"label editName\">" ) 761 .append( column.getLongLabel() ) 762 .append( ":</span><span class=\"editName\">" ) 763 .append( "<select name=\"editName\">" ) 764 .append( "<option />" ); 765 for( final DBEditConfig config : configs ) { 766 final String name = config.getEditName(); 767 buf.append( "<option value=\"" ).append( name ).append( '"' ); // 6.0.2.5 (2014/10/31) char を append する。 768 if( config.isCommon() ) { 769 buf.append( " class=\"commonEdit\"" ); 770 } 771 buf.append( "\">" ).append( name ).append( "</option>" ); 772 } 773 buf.append( "</select></span>" ); 774 return buf.toString(); 775 } 776 777 /** 778 * 【TAG】command を指定します。 779 * 780 * @og.tag 781 * command を指定します。 782 * [GET/LIST/SET/DELETE]のみが設定可能です。それ以外の場合、何も処理されません。 783 * 784 * @param cmd コマンド [GET/LIST/SET/DELETE] 785 */ 786 public void setCommand( final String cmd ) { 787 command = nval( getRequestParameter( cmd ),command ); 788 } 789 790 /** 791 * 【TAG】画面ID を指定します。 792 * 793 * @og.tag 794 * 画面ID を指定します。 795 * 796 * @param key 画面ID 797 */ 798 public void setGamenId( final String key ) { 799 gamenId = nval( getRequestParameter( key ),gamenId ); 800 } 801 802 /** 803 * 【TAG】編集名を指定します。 804 * 805 * @og.tag 806 * 編集名 を指定します。 807 * commandがSETまたはDELETEの場合は必須です。 808 * commandがGETまたはLISTの場合は無効です。 809 * 810 * @param name 編集名 811 */ 812 public void setEditName( final String name ) { 813 editName = nval( getRequestParameter( name ),editName ); 814 } 815 816 /** 817 * 【TAG】順番の入れ替えと、表示順の設定のみを行う場合にtrueにします(初期値:false)。 818 * 819 * @og.tag 820 * 順番の入れ替えと、表示順の設定のみを行う場合にtrueにします。 821 * 表示/非表示切替や、集計機能は利用できなくなります。 822 * (チェックボックスのリードオンリーはできないため、実際にはdisable+hiddenで出力しています) 823 * 初期値は、false:通常 です。 824 * 825 * @og.rev 5.5.5.2 (2012/08/10) 新規追加 826 * 827 * @param flag 順番入替のみ [true:入替のみ/false:通常] 828 */ 829 public void setOrderOnly( final String flag ) { 830 orderOnly = nval( getRequestParameter( flag ),orderOnly ); 831 } 832 833 /** 834 * このオブジェクトの文字列表現を返します。 835 * 基本的にデバッグ目的に使用します。 836 * 837 * @return このクラスの文字列表現 838 * @og.rtnNotNull 839 */ 840 @Override 841 public String toString() { 842 return ToString.title( this.getClass().getName() ) 843 .println( "VERSION" ,VERSION ) 844 .println( "command" ,command ) 845 .println( "gamenId" ,gamenId ) 846 .println( "editName" ,editName ) 847 .println( "Other..." ,getAttributes().getAttribute() ) 848 .fixForm().toString() ; 849 } 850}