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 = "8.2.0.2 (2022/06/24)" ; 095 private static final long serialVersionUID = 820220220624L ; 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 * @og.rev 7.0.1.0 (2018/10/15) XHTML → HTML5 対応(空要素の、"/>" 止めを、">" に変更します)。 251 * 252 * @param viewClms 表示カラム(CSV形式) 253 * @param config DBEditConfigオブジェクト 254 * 255 * @return 編集情報のHTML 256 * @og.rtnNotNull 257 */ 258 private String makeEditTable( final String viewClms , final DBEditConfig config ) { 259 final boolean useSum = getUseSum( viewClms ); 260 final String[] viewGroups = StringUtil.csv2Array( viewClms, '|' ); 261 262 final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE ) 263 .append( "<input type=\"hidden\" name=\"viewClms\" id=\"viewClms\" value=\"" ) 264 .append( viewClms ) 265// .append( "\"/><div /><div style=\"float:left;\">" ) // 6.4.5.0 (2016/04/08) そのdiv がないと、配置が狂うため、復活。 266 .append( "\"><div></div><div style=\"float:left;\">" ) // 6.4.5.0 (2016/04/08) そのdiv がないと、配置が狂うため、復活。 267 .append( makeLabelRow( useSum , config ) ) // 6.4.5.0 (2016/04/08) 268 .append( "</div><div id=\"clmLayer\" style=\"float:left; width:670px; overflow-x:scroll;\">" ); 269 270 for( int i=0; i<viewGroups.length; i++ ) { 271 if( i > 0 ) { 272 buf.append( makeSeparateRow( useSum ) ); 273 } 274 buf.append( "<table class=\"clmGroup\" style=\"float:left;\"><tr>" ); 275 final String[] clms = StringUtil.csv2Array( viewGroups[i] ); 276 for( int j=0; j<clms.length; j++ ) { 277 // 6.1.0.0 (2014/12/26) refactoring : Avoid if(x != y) ..; else ..; 278 final boolean isView = !StringUtil.startsChar( clms[j] , '!' ) ; // 6.4.1.1 (2016/01/16) 1文字 String.startsWith 279 // 6.4.1.1 (2016/01/16) 1文字 String.startsWith と、処理順の入れ替え 280 final String clm = isView ? clms[j] : clms[j].substring( 1 ) ; 281 if( "rowCount".equals( clm ) ) { continue; } 282 // 6.1.0.0 (2014/12/26) refactoring : Avoid if(x != y) ..; else ..; 283 buf.append( makeColumnRow( clm, isView, useSum, config ) ); 284 } 285 buf.append( "</tr></table>" ); 286 } 287 buf.append( "</div>" ); 288 289 // 6.1.1.0 (2015/01/17) useSum==true の場合のみ、表示する。 290 if( useSum ) { 291 // 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs) 292 if( config == null ) { 293 final String errMsg = "DBEditConfigが設定されていません。" ; 294 throw new OgRuntimeException( errMsg ); 295 } 296 297 final String grandTotalLabel = "<b>" + getDBColumn( GRANDTOTAL_PREFIX + "LABEL" ).getLongLabel() + ":</b>"; 298 final String firstTotalLabel = "<b>" + getDBColumn( FIRSTTOTAL_PREFIX + "LABEL" ).getLongLabel() + ":</b>"; // 6.1.1.0 (2015/01/17) 299 buf.append( "<div style=\"clear:both;\"><table>" ) 300 .append( makeCheckbox( GRANDTOTAL_PREFIX, config.useGrandTotal(), "h", grandTotalLabel, orderOnly ) ) // 5.5.5.2 (2012/08/10) 301 .append( makeCheckbox( FIRSTTOTAL_PREFIX, config.useFirstTotal(), "h", firstTotalLabel, orderOnly ) ) // 6.1.1.0 (2015/01/17) 302 .append( "</table></div>" ); 303 } 304 305 return buf.toString(); 306 } 307 308 /** 309 * 編集情報のヘッダー(ラベル行)のHTMLを生成します。 310 * 311 * @og.rev 5.4.2.0 (2011/12/01) 表示項目の全チェック機能を追加 312 * @og.rev 5.5.5.2 (2012/08/10) orderOnly対応 313 * @og.rev 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs) 314 * @og.rev 6.4.5.0 (2016/04/08) 共通ラベルは、共通チェックボックスを使用しないときは消します。 315 * @og.rev 6.4.5.0 (2016/04/08) DBEditConfigのローカル化。 316 * @og.rev 7.0.1.0 (2018/10/15) XHTML → HTML5 対応(空要素の、"/>" 止めを、">" に変更します)。 317 * 318 * @param useSum 集計対象のカラム(=NUMBER型)が存在しているか [true:存在/false:存在しない] 319 * @param config DBEditConfigオブジェクト 320 * 321 * @return 編集情報のヘッダー(ラベル行)のHTML 322 * @og.rtnNotNull 323 */ 324 private String makeLabelRow( final boolean useSum , final DBEditConfig config ) { 325 final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE ) 326 .append( "<table><tr><td style=\"margin:0px; padding:0px;\"><table>" ); 327 328 // 6.4.5.0 (2016/04/08) static final String CAN_EDIT_COMMON を使用 329 if( getUser().isAccess( CAN_EDIT_COMMON ) ) { 330 // 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs) 331 if( config == null ) { 332 final String errMsg = "DBEditConfigが設定されていません。" ; 333 throw new OgRuntimeException( errMsg ); 334 } 335 336 final String commonLabel = "<b>" + getDBColumn( COMMON_PREFIX + "LABEL" ).getLongLabel() + ":</b>"; // 6.4.5.0 (2016/04/08) else で使わなくなったので。 337 buf.append( makeCheckbox( COMMON_PREFIX, config.isCommon(), "h", commonLabel, orderOnly ) ); // 5.5.5.2 (2012/08/10) 338 } 339 else { 340 // 6.4.5.0 (2016/04/08) 共通ラベルは、共通チェックボックスを使用しないときは消します。 341 // buf.append( makeLabel( commonLabel ) ); 342 buf.append( makeLabel( "" ) ); 343 } 344 final String viewLabel = "<b>" + getDBColumn( VIEW_PREFIX + "LABEL" ).getLongLabel() + ":</b>"; 345 buf.append( makeCheckbox( "VIEW_ALL_CHECK", true, "h", viewLabel, orderOnly ) ); // 5.5.5.2 (2012/08/10) 346 if( useSum ) { 347 buf.append( makeLabel( SUM_PREFIX + "LABEL" ) ); 348 } 349 350 // 6.4.1.1 (2016/01/16) PMD refactoring. Avoid declaring a variable if it is unreferenced before a possible exit point. 351 final String groupLabel = "<b>" + getDBColumn( GROUP_PREFIX + "LABEL" ).getLongLabel() + "</b>" 352// + "<img id=\"groupBtn\" src=\"" + HybsSystem.sys( "JSP" ) + "/image/ball-green.gif\" />"; 353 + "<img id=\"groupBtn\" src=\"" + HybsSystem.sys( "JSP" ) + "/image/ball-green.gif\" >"; // 7.0.1.0 (2018/10/15) 354 buf.append( makeCell ( groupLabel, "h" ) ) 355 .append( makeLabel ( SUBTOTAL_PREFIX + "LABEL" ) ) 356 .append( makeLabel ( TOTAL_PREFIX + "LABEL" ) ) 357 .append( makeLabel ( ORDERBY_PREFIX + "LABEL" ) ) 358 .append( makeLabel ( DESC_PREFIX + "LABEL" ) ) 359 .append( "</table></td></tr></table>" ); 360 return buf.toString(); 361 } 362 363 /** 364 * 編集情報のカラム列のHTMLを生成します。 365 * 366 * @og.rev 5.5.5.2 (2012/08/10) orderOnly対応 367 * @og.rev 5.7.5.2 (2014/04/11) 降順はorderOnlyに関わらず編集可能にする 368 * @og.rev 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs) 369 * @og.rev 6.4.4.1 (2016/03/18) StringBuilderの代わりに、OgBuilderを使用する。 370 * 371 * @param clm カラム 372 * @param isView 表示のチェックボックス [true:初期ON/false:初期OFF] 373 * @param useSum 集計対象のカラム(=NUMBER型)が存在しているか [true:存在/false:存在しない] 374 * @param config 編集設定オブジェクト 375 * 376 * @return 編集情報のカラム列のHTMLを生成します。 377 * @og.rtnNotNull 378 */ 379 private String makeColumnRow( final String clm, final boolean isView, final boolean useSum, final DBEditConfig config ) { 380 // 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs) 381 if( table == null ) { 382 final String errMsg = "DBTableModelが設定されていません。" ; 383 throw new OgRuntimeException( errMsg ); 384 } 385 386 final int clmNo = table.getColumnNo( clm, false ); 387 final DBColumn column = ( clmNo < 0 ? getDBColumn( clm ) : table.getDBColumn( clmNo ) ); 388 389 return new OgBuilder() 390 .append( "<td name=\"" , clm ) 391 .append( "\" class=\"sortItem\" style=\"margin:0px; padding:0px;\">" ) 392 .append( "<table>" ) 393 .append( makeLabel ( column.getLongLabel() ) ) 394 .append( makeCheckbox( VIEW_PREFIX + clm, isView , "0", "", orderOnly ) ) // 5.5.5.2 (2012/08/10) 395 .appendIf( useSum , clm , 396 v -> makeCheckbox( SUM_PREFIX + v, config.isSumClm( v ) , "1", "", orderOnly, isNumberClm( v ) ) ) // 5.5.5.2 (2012/08/10) 397 .append( makeCheckbox( GROUP_PREFIX + clm, config.isGroupClm( clm ) , "0", "", orderOnly ) ) // 5.5.5.2 (2012/08/10) 398 .append( makeCheckbox( SUBTOTAL_PREFIX + clm, config.isSubTotalClm( clm ) , "1", "", orderOnly ) ) // 5.5.5.2 (2012/08/10) 399 .append( makeCheckbox( TOTAL_PREFIX + clm, config.isTotalClm( clm ) , "0", "", orderOnly ) ) // 5.5.5.2 (2012/08/10) 400 .append( makeInput ( ORDERBY_PREFIX + clm, config.getOrder( clm ) , "1", "" ) ) 401 .append( makeCheckbox( DESC_PREFIX + clm, config.isOrderByDesc( clm ) , "0", "", false ) ) // 5.7.5.1 (2014/04/11) 402 .append( "</table></td>" ) 403 .toString(); 404 } 405 406 /** 407 * チェックボックスのHTML文字列を生成します。 408 * 生成したHTMLは以下のようになります。 409 * 例)<tr><td class="row_[bgCnt]" ...>[prefix]<input type="checkbox" name="[clm]" ... /></td></tr> 410 * 411 * @param clm カラム 412 * @param checked 初期チェック [true:チェック済み/false:通常] 413 * @param bgCnt ゼブラ指定 [0/1/h] 414 * @param prefix チェックボックスのタグの前に挿入するHTML文字列 415 * @param readonly リードオンリー指定 [true:読取専用/false:読書可] 416 * 417 * @og.rev 5.5.5.2 (2012/08/10) readOnly追加 418 * @og.rev 6.1.1.0 (2015/01/17) 内部構造を見直します。 419 * 420 * @return チェックボックスのHMTL文字列 421 */ 422 private String makeCheckbox( final String clm, final boolean checked, final String bgCnt, final String prefix, final boolean readonly ) { 423 return makeCheckbox( clm, checked, bgCnt, prefix, readonly, true ); 424 } 425 426 /** 427 * チェックボックスのHTML文字列を生成します。 428 * 生成したHTMLは以下のようになります。 429 * 例)<tr><td class="row_[bgCnt]" ...>[prefix]<input type="checkbox" name="[clm]" ... /></td></tr> 430 * 431 * isChbox(チェックボックス生成) を、true に指定すると、チェックボックスのinputタグを生成します。 432 * 433 * @og.rev 5.5.5.2 (2012/08/10) readOnly追加 434 * @og.rev 6.1.1.0 (2015/01/17) 内部構造を見直します。 435 * 436 * @param clm カラム 437 * @param checked 初期チェック [true:チェック済み/false:通常] 438 * @param bgCnt ゼブラ指定 [0/1/h] 439 * @param prefix チェックボックスのタグの前に挿入するHTML文字列(nullは禁止) 440 * @param readonly リードオンリー指定 [true:読取専用/false:読書可] 441 * @param isChbox チェックボックス生成 [true:生成する/false:生成しない] 442 * 443 * @return チェックボックスのHMTL文字列 444 */ 445 private String makeCheckbox( final String clm, final boolean checked, final String bgCnt, final String prefix, final boolean readonly, final boolean isChbox ) { 446 if( isChbox ) { 447 448 // 6.1.1.0 (2015/01/17) TagBufferの連結記述 449 final String tag = new TagBuffer( "input" ) 450 .add( "type" , "checkbox" ) 451 .add( "name" , clm ) 452 .add( "value" , "1" ) 453 .add( "checked" , "checked" , checked ) 454 .add( "disabled", "disabled", readonly ) 455 .makeTag(); 456 457 // 6.1.1.0 (2015/01/17) TagBufferの連結記述 458 final String cell = readonly && checked // 6.1.1.0 (2015/01/17) suffix 処理を変更 459 ? tag + new TagBuffer( "input" ) 460 .add( "type", "hidden" ) 461 .add( "name", clm ) 462 .add( "value", "1" ) 463 .makeTag() 464 : tag ; 465 466 return makeCell( prefix + cell , bgCnt ); // 6.1.1.0 (2015/01/17) prefix に、null は禁止 467 } 468 else { 469 return makeCell( prefix + " ", bgCnt ); // 6.1.1.0 (2015/01/17) prefix に、null は禁止 470 } 471 } 472 473 /** 474 * テキスト入力HTML文字列を生成します。 475 * 生成したHTMLは以下のようになります。 476 * 例)<tr><td class="row_[bgCnt]" ...>[prefix]<input type="text" name="[clm]" ... /></td></tr> 477 * 478 * @param clm カラム 479 * @param value 値 480 * @param bgCnt ゼブラ指定 [0/1/h] 481 * @param prefix チェックボックスのタグの前に挿入するHTML文字列(nullは禁止) 482 * 483 * @return チェックボックスのHMTL文字列 484 */ 485 private String makeInput( final String clm, final String value, final String bgCnt, final String prefix ) { 486 // 6.1.1.0 (2015/01/17) TagBufferの連結記述 487 final String tag = new TagBuffer( "input" ) 488 .add( "type" , "text" ) 489 .add( "name" , clm ) 490 .add( "value" , value ) 491 .add( "style" , "width:10px; font-size:10px;" ) 492 .add( "maxlength" , "2" ) 493 .add( "class" , "S9" ) 494 .makeTag(); 495 496 return makeCell( prefix + tag , bgCnt ); // 6.1.1.0 (2015/01/17) prefix に、null は禁止 497 } 498 499 /** 500 * 左右分割されている際の分割列のHTML文字列を生成します。 501 * 502 * @og.rev 6.4.4.1 (2016/03/18) StringBuilderの代わりに、OgBuilderを使用する。 503 * 504 * @param useSum 集計対象のカラム(=NUMBER型)が存在しているか [true:存在している/false:存在していない] 505 * 506 * @return チェックボックスのHMTL文字列 507 * @og.rtnNotNull 508 */ 509 private String makeSeparateRow( final boolean useSum ) { 510 final String ROW_H = makeCell( " ", "h" ) ; 511 512 return new OgBuilder() 513 .append( "<table style=\"float:left;\"><tr><td style=\"margin:0px; padding:0px;\"><table>" ) 514 .append( ROW_H ) // ラベル 515 .append( ROW_H ) // 表示 516 .appendIf( useSum , ROW_H ) // 集計項目 517 .append( ROW_H ) // 集計キー 518 .append( ROW_H ) // 小計キー 519 .append( ROW_H ) // 合計キー 520 .append( ROW_H ) // 表示順 521 .append( ROW_H ) // 昇順・降順 522 .append( "</table></td></tr></table>") 523 .toString(); 524 } 525 526 /** 527 * ラベルのHTML文字列を生成します。 528 * 529 * @param clm カラム 530 * 531 * @return ラベルのHTML文字列 532 */ 533 private String makeLabel( final String clm ) { 534 return makeCell( getDBColumn( clm ).getLongLabel(), "h" ); 535 } 536 537 /** 538 * セルのHTML文字列を生成します。 539 * 540 * body 属性は、HTML文字列を指定します。 541 * bgCnt は、背景色のゼブラカラーの指定の為の class 属性で、[0/1/h] が指定できます。 542 * 例えば、"0" を指定した場合は、class="row_0" のように、属性を付与します。 543 * 標準の CSSファイルで設定しているのが、[0/1/h] なだけで、上記 class 属性を 544 * custom.css で設定すれば、どのような文字列でも指定可能です。 545 * 546 * @og.rev 6.1.1.0 (2015/01/17) 内部構造を見直します。 547 * @og.rev 8.2.0.2 (2022/06/24) HTML5廃止対応 548 * 549 * @param body tdタグ内のHTML文字列 550 * @param bgCnt ゼブラ指定 [0/1/h] 551 * 552 * @return セルのHTML文字列 553 * @og.rtnNotNull 554 */ 555 private String makeCell( final String body, final String bgCnt ) { 556// return "<tr><td align=\"center\" style=\"height:22px;\" class=\"row_" + bgCnt + "\">" + body + "</td></tr>"; 557 return "<tr><td style=\"text-align:center; height:22px;\" class=\"row_" + bgCnt + "\">" + body + "</td></tr>"; // 8.2.0.2 (2022/06/24) Modify 558 } 559 560 /** 561 * この編集設定で集計対象のカラム(=NUMBER型)が存在しているかを返します。 562 * 563 * @param viewClms カラム 564 * 565 * @return 集計対象のカラム(=NUMBER型)が存在しているか 566 */ 567 private boolean getUseSum( final String viewClms ) { 568 if( viewClms == null ) { return false; } 569 570 final String[] clms = StringUtil.csv2Array( viewClms.replace( '|', ',' ) ); 571 for( int j=0; j<clms.length; j++ ) { 572 // 6.1.0.0 (2014/12/26) refactoring : Avoid if(x != y) ..; else ..; 573 final String clm = StringUtil.startsChar( clms[j] , '!' ) ? clms[j].substring( 1 ) : clms[j] ; // 6.4.1.1 (2016/01/16) 1文字 String.startsWith 574 if( isNumberClm( clm ) ) { return true; } // ひとつでも見つかれば、true 575 } 576 return false; 577 } 578 579 /** 580 * 引数のカラムがNUMBER型かどうかをチェックします。 581 * 582 * @og.rev 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs) 583 * @og.rev 6.4.4.2 (2016/04/01) contains 判定を行う新しいメソッドを使用します。 584 * @og.rev 6.4.6.0 (2016/05/27) isNumber , isDate 追加。 585 * 586 * @param clm カラム 587 * 588 * @return NUMBER型かどうか 589 */ 590 private boolean isNumberClm( final String clm ) { 591 if( clm == null ) { return false; } 592 // 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs) 593 if( table == null ) { 594 final String errMsg = "DBTableModelが設定されていません。" ; 595 throw new OgRuntimeException( errMsg ); 596 } 597 598 final int no = table.getColumnNo( clm, false ); 599 if( no >= 0 ) { 600 final DBColumn dbClm = table.getDBColumn( no ); 601 // 6.0.0.1 (2014/04/25) These nested if statements could be combined 602 // 6.4.4.2 (2016/04/01) contains 判定を行う新しいメソッドを使用します。 603 return dbClm != null && dbClm.isNumberType(); 604 } 605 return false; 606 } 607 608 /** 609 * 編集設定情報を保存します。 610 * 611 * @og.rev 6.1.1.0 (2015/01/17) 総合計を最初の行に追加するかどうか(FirstTotal)の属性を追加 612 * @og.rev 6.4.5.0 (2016/04/08) UserInfo のEditConfig関連機能を、DBEditConfigManagerに移植します。 613 * @og.rev 5.9.18.1 (2017/03/24) 共通の編集名対応 614 * @og.rev 6.9.2.1 (2018/03/12) DBEditConfigManagerを直接取り出す処理を、廃止します 615 * 616 */ 617// private void saveEditConfig( final DBEditConfigManager dbConfMgr ) { 618 private void saveEditConfig() { 619 final String viewClms = getRequest().getParameter( "viewClms" ); 620 final String sumClms = getColumns( SUM_PREFIX ); 621 final String groupClms = getColumns( GROUP_PREFIX ); 622 final String subTotalClms = getColumns( SUBTOTAL_PREFIX ); 623 final String totalClms = getColumns( TOTAL_PREFIX ); 624 final String useGrandTotal = getRequest().getParameter( GRANDTOTAL_PREFIX ); 625 final String useFirstTotal = getRequest().getParameter( FIRSTTOTAL_PREFIX ); // 6.1.1.0 (2015/01/17) 626 final String orderByClms = getOrderByColumns(); 627 final String isCommon = getRequest().getParameter( COMMON_PREFIX ); 628 629 // 5.9.18.1 (2017/03/24) ADD 編集名の共通判別対応 630 // 共通で、編集名の頭に「*」が無い場合 631// if("1".equals( isCommon ) && !('*' == editName.charAt( 0 ))){ // 7.2.9.4 (2020/11/20) 632 if( "1".equals( isCommon ) && '*' != editName.charAt( 0 ) ){ 633 // 編集名の頭に「*」を付与 634 editName = "*"+editName; 635 } 636 // 編集名をリクエストスコープに設定 637 setRequestAttribute("regEditName", editName); 638 639 final DBEditConfig config 640 = new DBEditConfig( editName, viewClms, sumClms, groupClms 641 , subTotalClms, totalClms, useGrandTotal, useFirstTotal, orderByClms, isCommon ); 642 643 getUser().addEditConfig( gamenId, editName, config ); // 6.4.5.0 (2016/04/08) 暫定的に残す 644 // dbConfMgr.addEditConfig( gamenId, editName, config ); 645 } 646 647 /** 648 * 編集設定情報を削除します。 649 * 650 * ※ org.opengion.hayabusa.resource.UserInfo#deleteEditConfig( String , String )でも 651 * 処理しているが、本来は、UserInfoでは処理しないほうが良いため、 652 * 今回は、こちらで判定して処理します。 653 * 654 * @og.rev 6.4.5.0 (2016/04/08) 共通設定した editName が削除できてしまうため、ロール制御を追加します。 655 * @og.rev 6.4.5.0 (2016/04/08) UserInfo のEditConfig関連機能を、DBEditConfigManagerに移植します。 656 * @og.rev 6.9.2.1 (2018/03/12) DBEditConfigManagerを直接取り出す処理を、廃止します 657 * 658 * @param config DBEditConfigオブジェクト 659 */ 660// private void deleteEditConfig( final DBEditConfigManager dbConfMgr , final DBEditConfig config ) { 661 private void deleteEditConfig( final DBEditConfig config ) { 662 final boolean isCommon = config.isCommon(); 663 // 共通で、かつ、共通設定ロールを持っていない場合は、エラーにします。 664 if( isCommon && !getUser().isAccess( CAN_EDIT_COMMON ) ) { 665 final String errMsg = "共通設定されている編集名を削除する権限がありません。"; 666 throw new HybsSystemException( errMsg ); 667 } 668 else { 669 getUser().deleteEditConfig( gamenId, editName ); // 6.4.5.0 (2016/04/08) 暫定的に残す 670 // dbConfMgr.deleteEditConfig( gamenId, editName ); 671 } 672 } 673 674 /** 675 * パラメーターから引数のプレフィックスをキーに、チェックされたカラム一覧(CSV形式)を返します。 676 * 677 * @param prefixKey 各キーの取得するためのプレフィックス 678 * 679 * @return カラム一覧(CSV形式) 680 * @og.rtnNotNull 681 */ 682 private String getColumns( final String prefixKey ) { 683 final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE ); 684 685 final Enumeration<?> enume = getParameterNames(); 686 while( enume.hasMoreElements() ) { 687 final String key = (String)(enume.nextElement()); 688 if( key.startsWith( prefixKey ) ) { 689 final String val = getRequest().getParameter( key ); 690 if( "1".equals( val ) ) { 691 final String clm = key.substring( prefixKey.length() ); 692 if( buf.length() > 0 ) { buf.append( ',' ); } // 6.0.2.5 (2014/10/31) char を append する。 693 buf.append( clm ); 694 } 695 } 696 } 697 698 return buf.toString(); 699 } 700 701 /** 702 * 表示順のカラム一覧(CSV形式)を返します。 703 * 704 * @og.rev 6.4.3.4 (2016/03/11) CSV形式の文字連結を、stream 経由で行います。 705 * 706 * @return 表示順のカラム一覧(CSV形式) 707 * @og.rtnNotNull 708 */ 709 private String getOrderByColumns() { 710 final Enumeration<?> enume = getParameterNames(); 711 final List<Integer> orderNo = new ArrayList<>(); 712 final Map<Integer,String> odrClmMap = new HashMap<>(); 713 while( enume.hasMoreElements() ) { 714 final String key = (String)(enume.nextElement()); 715 if( key.startsWith( ORDERBY_PREFIX ) ) { 716 final String val = getRequest().getParameter( key ); 717 if( val != null && val.length() > 0 ) { 718 String clm = key.substring( ORDERBY_PREFIX.length() ); 719 final String desc = getRequest().getParameter( DESC_PREFIX + clm ); 720 if( "1".equals( desc ) ) { 721 clm = "!" + clm; 722 } 723 // 数字項目以外が入力された場合は無視 724 Integer odno = null; 725 try { 726 odno = Integer.valueOf( val ); 727 } 728 catch( final NumberFormatException ex ) { 729 continue; 730 } 731 String str = odrClmMap.get( odno ); 732 // 同じ番号の場合でも重ならないように振り直しする。 733 while( str != null ) { 734 odno = Integer.valueOf( odno.intValue() + 1 ); 735 str = odrClmMap.get( odno ); 736 } 737 odrClmMap.put( odno, clm ); 738 orderNo.add( odno ); 739 } 740 } 741 } 742 743 Collections.sort( orderNo ); 744 745 // 6.4.3.4 (2016/03/11) CSV形式の文字連結を、stream 経由で行います。 746 return orderNo.stream() 747 .map( no -> odrClmMap.get( no ) ) 748 .collect( Collectors.joining( "," ) ); 749 } 750 751 /** 752 * 編集設定一覧のプルダウンメニューを作成します。 753 * 754 * @og.rev 7.0.1.0 (2018/10/15) XHTML → HTML5 対応(空要素の、"/>" 止めを、">" に変更します)。 755 * 756 * @param configs DBEditConfig配列(可変長引数) 757 * 758 * @return 編集一覧のプルダウン 759 * @og.rtnNotNull 760 */ 761 private String getEditSelect( final DBEditConfig... configs ) { 762 final DBColumn column = getDBColumn( "editName" ); 763 764 final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE ) 765 .append( "<span class=\"label editName\">" ) 766 .append( column.getLongLabel() ) 767 .append( ":</span><span class=\"editName\">" ) 768 .append( "<select name=\"editName\">" ) 769// .append( "<option />" ); 770 .append( "<option></option>" ); // 7.0.1.0 (2018/10/15) 771 for( final DBEditConfig config : configs ) { 772 final String name = config.getEditName(); 773 buf.append( "<option value=\"" ).append( name ).append( '"' ); // 6.0.2.5 (2014/10/31) char を append する。 774 if( config.isCommon() ) { 775 buf.append( " class=\"commonEdit\"" ); 776 } 777 buf.append( "\">" ).append( name ).append( "</option>" ); 778 } 779 buf.append( "</select></span>" ); 780 return buf.toString(); 781 } 782 783 /** 784 * 【TAG】command を指定します。 785 * 786 * @og.tag 787 * command を指定します。 788 * [GET/LIST/SET/DELETE]のみが設定可能です。それ以外の場合、何も処理されません。 789 * 790 * @param cmd コマンド [GET/LIST/SET/DELETE] 791 */ 792 public void setCommand( final String cmd ) { 793 command = nval( getRequestParameter( cmd ),command ); 794 } 795 796 /** 797 * 【TAG】画面ID を指定します。 798 * 799 * @og.tag 800 * 画面ID を指定します。 801 * 802 * @param key 画面ID 803 */ 804 public void setGamenId( final String key ) { 805 gamenId = nval( getRequestParameter( key ),gamenId ); 806 } 807 808 /** 809 * 【TAG】編集名を指定します。 810 * 811 * @og.tag 812 * 編集名 を指定します。 813 * commandがSETまたはDELETEの場合は必須です。 814 * commandがGETまたはLISTの場合は無効です。 815 * 816 * @param name 編集名 817 */ 818 public void setEditName( final String name ) { 819 editName = nval( getRequestParameter( name ),editName ); 820 } 821 822 /** 823 * 【TAG】順番の入れ替えと、表示順の設定のみを行う場合にtrueにします(初期値:false)。 824 * 825 * @og.tag 826 * 順番の入れ替えと、表示順の設定のみを行う場合にtrueにします。 827 * 表示/非表示切替や、集計機能は利用できなくなります。 828 * (チェックボックスのリードオンリーはできないため、実際にはdisable+hiddenで出力しています) 829 * 初期値は、false:通常 です。 830 * 831 * @og.rev 5.5.5.2 (2012/08/10) 新規追加 832 * 833 * @param flag 順番入替のみ [true:入替のみ/false:通常] 834 */ 835 public void setOrderOnly( final String flag ) { 836 orderOnly = nval( getRequestParameter( flag ),orderOnly ); 837 } 838 839 /** 840 * このオブジェクトの文字列表現を返します。 841 * 基本的にデバッグ目的に使用します。 842 * 843 * @return このクラスの文字列表現 844 * @og.rtnNotNull 845 */ 846 @Override 847 public String toString() { 848 return ToString.title( this.getClass().getName() ) 849 .println( "VERSION" ,VERSION ) 850 .println( "command" ,command ) 851 .println( "gamenId" ,gamenId ) 852 .println( "editName" ,editName ) 853 .println( "Other..." ,getAttributes().getAttribute() ) 854 .fixForm().toString() ; 855 } 856}