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.resource; 017 018import java.util.Arrays; 019import java.util.HashMap; 020import java.util.concurrent.ConcurrentMap; // 6.4.3.3 (2016/03/04) 021import java.util.concurrent.ConcurrentHashMap; // 6.4.3.1 (2016/02/12) refactoring 022import java.util.HashSet; 023import java.util.LinkedHashMap; 024import java.util.Map; 025import java.util.Set; 026import java.util.LinkedHashSet; // 8.0.0.0 (2021/10/01) 027 028import java.util.stream.Stream; // 6.4.1.1 (2016/01/16) 029import java.util.stream.Collectors; // 6.4.1.1 (2016/01/16) 030 031import org.opengion.fukurou.util.ErrMsg; 032import org.opengion.fukurou.util.StringUtil; 033import org.opengion.fukurou.db.DBUtil; // 7.2.9.2 (2020/10/30) 034import org.opengion.fukurou.db.ApplicationInfo; // 7.2.9.2 (2020/10/30) 035import org.opengion.hayabusa.common.HybsSystem; // 7.2.9.2 (2020/10/30) 036import org.opengion.hayabusa.common.HybsSystemException; // 6.4.3.3 (2016/03/04) 037import org.opengion.hayabusa.db.DBColumn; 038import org.opengion.hayabusa.db.DBColumnConfig; 039import static org.opengion.fukurou.system.HybsConst.BUFFER_LARGE; // 6.1.0.0 (2014/12/26) refactoring 040 041/** 042 * java.util.ResourceBundle クラスを複数管理するリソースクラスです。 043 * 044 * ResourceManager は、 045 * LabelResource.properties ラベルリソース(テーブル定義やカラム名などの画面に表示するリソース) 046 * CodeResource.properties コードリソース(選択データなどプルダウンメニューで選択するリソース) 047 * MessageResource.properties メッセージリソース(エラーコードやメッセージなどを表示するリソース) 048 * 049 * の3つのプロパティーファイルを内部に持っており、それぞれのメソッドにより、 050 * リソースの返す値を決めています。 051 * 052 * ResourceManagerは、単独でも生成できますが、各ユーザー毎に作成するよりも 053 * ResourceFactory#newInstance( lang )メソッドより生成した方が、プーリングされるので 054 * 効率的です。 055 * 056 * リソース作成時に指定するロケールは、ISO 言語コード(ISO-639 で定義される 2 桁の小文字) 057 * <a href ="http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt"> 058 * http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt</a>を使用して下さい。 059 * ただし、内部的に Locale を構築していますが、その正しさは、チェックされていませんので、 060 * 指定するロケールに応じた properties ファイルを用意しておいて下さい。 061 * 062 * 日本語の場合は、言語コードは "jp" なので、 063 * LabelResource_jp.properties ラベルリソース(日本語) 064 * CodeResource_jp.properties コードリソース(日本語) 065 * MessageResource_jp.properties メッセージリソース(日本語) 066 * 067 * を用意して下さい。 068 * 069 * CodeResource については、リソースファイルから CodeSelectionオブジェクトを 070 * 作成して利用します。この、CodeSelectionオブジェクトの作成方法として、 071 * 3通り考えられます。 072 * 1つ目は、毎回 要求が発生する毎に CodeSelection を作成し、プールしていきます。こうすることで、 073 * 初めて使用されたときだけオブジェクト化されますので、メモリの節約が可能です。ただし、 074 * プールにヒットしなかった場合は、やはりリソースから検索しますので、元々ヒットしない 075 * キーに対しては、毎回リソースを検索するため、非効率です。 076 * 2つめは、元々ヒットしないキーに対して、NullCodeSelectionオブジェクトを登録しておくことで、 077 * プールにため込んで行くと言う方法です。この場合は、シングルトーンにしてメモリを節約しますが、 078 * それでもプール自体の容量は、確保しておく必要があります。 079 * 3つめは、この ResourceManager がインスタンス化されるときに、すべての CodeSelectionオブジェクトを 080 * あらかじめ プールしておく方法です。使わない CodeSelection もインスタンス化する変わりに、 081 * キャッシュにヒットしない場合は、即 CodeSelection が存在しないと判断できるため、 082 * もっともパフォーマンスが高くなります。 083 * 本 ResourceManager の実装は、3つめの、あらかじめ、すべてをキャッシュしておく方法を 084 * 採用しています。 085 * 086 * @og.group リソース管理 087 * 088 * @version 4.0 089 * @author Kazuhiko Hasegawa 090 * @since JDK5.0, 091 */ 092public final class ResourceManager { 093 /** 7.2.9.2 (2020/10/30) ベースとなるSYSTEM_ID(RESOURCE_BASE_SYSTEM_ID)の取得 */ 094 private static final String QUERY = "select PARAM from GE12" 095 + " where SYSTEM_ID=? and FGJ='1' and PARAM_ID='RESOURCE_BASE_SYSTEM_ID'"; 096 097 /** 7.2.9.2 (2020/10/30) リソースの接続先を、取得します。 */ 098 private final String DBID = HybsSystem.sys( "RESOURCE_DBID" ); 099 100 private final ColumnDataLoader columnLoader ; 101 private final CodeDataLoader codeLoader; 102 private final LabelDataLoader labelLoader; 103 private final GUIDataLoader guiLoader; 104 105 /** 6.4.3.1 (2016/02/12) PMD refactoring. HashMap → ConcurrentHashMap に置き換え。 */ 106 private final ConcurrentMap<String,DBColumn> columnPool = new ConcurrentHashMap<>( BUFFER_LARGE ); 107 108 private final String lang ; 109 110 /** 111 * コンストラクター 112 * システムIDと言語コードを指定して、生成します。 113 * 114 * @og.rev 7.2.9.2 (2020/10/30) ベースとなるSYSTEM_ID(RESOURCE_BASE_SYSTEM_ID)の取得 115 * @og.rev 8.0.0.0 (2021/10/01) RESOURCE_BASE_SYSTEM_ID は、CSV形式で複数指定できる(先頭優先)。 116 * 117 * @param systemId システムID 118 * @param lang 言語コード 119 * @param initLoad リソースデータの先読み可否(true:先読みする) 120 */ 121 public ResourceManager( final String systemId,final String lang,final boolean initLoad ) { 122 this.lang = lang; 123 124 // 8.0.0.0 (2021/10/01) 125 final Set<String> sysSet = new LinkedHashSet<>(); // 順序をキープし、重複を排除する。 126 sysSet.add( systemId ); // 通常システムIDは、一番最初 127 128 // 7.2.9.2 (2020/10/30) ベースとなるSYSTEM_ID(RESOURCE_BASE_SYSTEM_ID)の取得 129 // 8.5.4.2 (2024/01/12) PMD 7.0.0 UseShortArrayInitializer 130// final String[] args = new String[] { systemId }; 131 final String[] args = { systemId }; 132 final String[][] vals = DBUtil.dbExecute( QUERY,args,(ApplicationInfo)null,DBID ); 133// final String baseSys = vals != null && vals.length > 0 && vals[0].length > 0 && vals[0][0].length() > 0 ? 134// StringUtil.nval( vals[0][0] , "**" ) : "**" ; 135 if( vals != null && vals.length > 0 && vals[0].length > 0 && vals[0][0].length() > 0 ) { 136 for( final String sysId : vals[0][0].split( "," ) ) { // AA,BB,CC 形式を分割 137 final String sys = sysId.trim(); 138 if( !sys.isEmpty() ) { sysSet.add( sys ); } // 空文字列は登録しない。 139 } 140 } 141 sysSet.add( "**" ); // "**" は、一番最後に追加する。 142 143// final String[] sysAry = sysSet.toArray( new String[sysSet.size()] ); 144 final String[] sysAry = sysSet.toArray( new String[0] ); // 8.5.4.2 (2024/01/12) PMD 7.0.0 OptimizableToArrayCall 対応 145 146// columnLoader = new ColumnDataLoader( systemId,baseSys,initLoad ); 147// labelLoader = new LabelDataLoader( systemId,baseSys,lang,initLoad ); 148// codeLoader = new CodeDataLoader( systemId,baseSys,initLoad,labelLoader ); 149// guiLoader = new GUIDataLoader( systemId,baseSys ); 150 151 columnLoader = new ColumnDataLoader( sysAry,initLoad ); 152 labelLoader = new LabelDataLoader( sysAry,lang,initLoad ); 153 codeLoader = new CodeDataLoader( sysAry,initLoad,labelLoader ); 154 guiLoader = new GUIDataLoader( sysAry ); 155 } 156 157 /** 158 * 設定されている言語を返します。 159 * 160 * @return 言語 161 */ 162 public String getLang() { 163 return lang; 164 } 165 166// /** 167// * ColumnResource オブジェクトを取得します。 168// * ColumnResourceのキャシュはここでは行わず、DBColumnFactoryクラス内で行います。 169// * 170// * @og.rev 8.5.6.0 (2024/02/29) DBColumn を resource パッケージから外すための処置 171// * 172// * @param key カラムID(not null) 173// * 174// * @return ColumnResourceオブジェクト 175// */ 176// public ColumnResource getColumnResource( final String key ) { 177// // 6.4.3.3 (2016/03/04) ConcurrentHashMap の not null制限のチェック追加 178// if( key == null ) { 179// final String errMsg = "カラムIDに、NULL は指定できません。"; 180// throw new HybsSystemException( errMsg ); 181// } 182// 183// final ColumnData clmDt = columnLoader.getColumnData( key ); 184// if( clmDt == null ) { 185// final String errMsg = "データベース上にカラムリソースが定義されていません。key=[" + key + "]"; 186// throw new HybsSystemException( errMsg ); 187// } 188// 189// // 8.5.5.1 (2024/02/29) PMD 7.0.0 LocalVariableNamingConventions 190// final String labelClm = clmDt.getLabelColumn(); 191// final String codeClm = clmDt.getCodeColumn(); 192// 193// return new ColumnResource( 194// lang, 195// clmDt, 196// labelLoader.getLabelData( labelClm ), 197// codeLoader.getCodeData( codeClm ) ); 198// } 199// } 200 201 /** 202 * DBColumn オブジェクトを取得します。 203 * 作成したDBColumnオブジェクトは、内部にプールしておき、同じオブジェクト要求が 204 * あったときは、プールのオブジェクトを利用して、DBColumnを返します。 205 * 206 * @og.rev 3.4.0.0 (2003/09/01) ラベルカラム、コードカラム、表示パラメータ、編集パラメータ、文字パラメータの追加。 207 * @og.rev 3.5.6.4 (2004/07/16) 追加パラメータ取り込み時に、"_" は、null 扱いとする。 208 * @og.rev 3.6.0.7 (2004/11/06) DBColumn の official属性追加 209 * @og.rev 6.4.3.3 (2016/03/04) ConcurrentHashMap の not null制限のチェック追加 210 * 211 * @param key カラムID(not null) 212 * 213 * @return DBColumnオブジェクト 214 */ 215 public DBColumn getDBColumn( final String key ) { 216 // 6.4.3.3 (2016/03/04) ConcurrentHashMap の not null制限のチェック追加 217 if( key == null ) { 218 final String errMsg = "カラムIDに、NULL は指定できません。"; 219 throw new HybsSystemException( errMsg ); 220 } 221 222 DBColumn clm = columnPool.get( key ); 223 if( clm == null ) { 224 final ColumnData clmDt = columnLoader.getColumnData( key ); 225 if( clmDt != null ) { 226 // 8.5.5.1 (2024/02/29) PMD 7.0.0 LocalVariableNamingConventions 227// final String label_clm = clmDt.getLabelColumn(); 228// final String code_clm = clmDt.getCodeColumn(); 229 final String labelClm = clmDt.getLabelColumn(); 230 final String codeClm = clmDt.getCodeColumn(); 231 232 clm = new DBColumn( 233 lang, 234 clmDt, 235// labelLoader.getLabelData( label_clm ), 236// codeLoader.getCodeData( code_clm ) ); 237 labelLoader.getLabelData( labelClm ), 238 codeLoader.getCodeData( codeClm ) ); 239 240 columnPool.put( key,clm ); 241 } 242 } 243 return clm; 244 } 245 246 /** 247 * DBColumn オブジェクトを作成します。 248 * 内部にプールに存在すればそれを、なければ新規に作成します。 249 * それでも存在しない場合は、DBColumnConfig より、ラベルと言語を指定して 250 * 新規に作成します。 251 * 252 * @param key カラムID(not null) 253 * 254 * @og.rev 7.1.0.0 (2020/01/27) LabelDataを直接呼び出します。 255 * 256 * @return DBColumnオブジェクト 257 * @see #getDBColumn( String ) 258 */ 259 public DBColumn makeDBColumn( final String key ) { 260 DBColumn dbColumn = getDBColumn( key ); 261 if( dbColumn == null ) { 262 final DBColumnConfig config = new DBColumnConfig( key ); 263 config.setLabelData( labelLoader.getLabelData( key ) ); // 7.1.0.0 (2020/01/27) 264 config.setLang( lang ); 265 dbColumn = new DBColumn( config ); 266 } 267 return dbColumn; 268 } 269 270 /** 271 * DBColumn オブジェクトを作成します。 272 * 内部にプールに存在すればそれを、なければ新規に作成します。 273 * それでも存在しない場合は、DBColumnConfig より、ラベルと言語を指定して 274 * 新規に作成します。 275 * lbl引数が、nullか、ゼロ文字列の場合は、#makeDBColumn(String) と同じです。 276 * 277 * @og.rev 6.9.1.0 (2018/02/26) unionLbls追加 278 * @og.rev 7.1.0.0 (2020/01/27) LabelDataを直接呼び出します。 279 * 280 * @param key カラムID(not null) 281 * @param lbl ラベル(nullか、ゼロ文字列の場合は、設定しません) 282 * 283 * @return DBColumnオブジェクト 284 * @see #getDBColumn( String ) 285 */ 286 public DBColumn makeDBColumn( final String key , final String lbl ) { 287 if( lbl == null || lbl.isEmpty() ) { return makeDBColumn( key ); } 288 289 final DBColumn dbColumn = getDBColumn( key ); 290 final DBColumnConfig config ; 291 292 if( dbColumn == null ) { 293 config = new DBColumnConfig( key ); 294 config.setLang( lang ); 295 } 296 else { 297 config = dbColumn.getConfig(); 298 } 299 300 config.setLabelData( labelLoader.getLabelData( lbl ) ); // 7.1.0.0 (2020/01/27) 301 302 return new DBColumn( config ); 303 } 304 305 /** 306 * メッセージリソースからキーで指定されたメッセージに、 307 * 引数で指定された変数値をセットしたメッセージを返します。 308 * 309 * このメッセージは、リソースで選ばれたロケール毎のメッセージに、 310 * MessageFormat#format でフォーマットする事により作成されます。 311 * メッセージがリソースに存在しない場合はキーを返します。 312 * 313 * @og.rev 4.0.0.0 (2005/01/31) オラクルとWindowsとの間の "~"の文字化け対策 314 * @og.rev 4.0.0.0 (2007/10/17) メッセージリソース統合に伴いラベルローダーを使用する 315 * @og.rev 4.0.0.0 (2007/10/18) 名称変更 getMessage ⇒ getLabel 316 * @og.rev 5.1.1.0 (2009/12/01) #XXXXの変換で、カラム名が複数指定されている場合の対応 317 * @og.rev 6.1.0.0 (2014/12/26) LabelData が存在しなかった場合の処理 318 * @og.rev 6.3.9.0 (2015/11/06) labelLoader.getLabelDataは、nullを返しません。 319 * @og.rev 6.6.0.0 (2016/12/01) 引数の配列を可変長配列に変更します。 320 * @og.rev 7.0.7.0 (2019/12/13) #getLabel( String ) と統合します。 321 * 322 * @param key キー 323 * @param args メッセージの配列 324 * 325 * @return メッセージ(無ければ キー) 326 */ 327 public String getLabel( final String key,final String... args ) { // 6.6.0.0 (2016/12/01) 328 final LabelData lblData = labelLoader.getLabelData( key ); 329 330 final String msglbl ; 331 332 if( args == null || args.length == 0 ){ 333 msglbl = lblData.getLabel(); 334 } 335 else { 336 // 6.1.0.0 (2014/12/26) メソッド化 337 final String[] msgArgs = makeLabelArray( args ); // 6.1.0.0 (2014/12/26) メソッド化 338 339 // 6.1.0.0 (2014/12/26) LabelData が存在しなかった場合の処理 340 // 6.3.9.0 (2015/11/06) labelLoader.getLabelDataは、nullを返しません。 341 msglbl = lblData.getMessage( msgArgs ); 342 } 343 344 return msglbl == null ? key : msglbl ; // なければ key を返す 345 } 346 347 /** 348 * ラベルリソースから、ラベルを返します。 349 * ただし、キーに、「スペース+%+記号」を判定、処理する機能を用意します。 350 * 351 * 記号は、Label,Short,Tips,Description,RawShortLabel,CodeData の頭文字一つ目です。 352 * ('L','S','T','D','R','C') となります。 353 * 'L' は通常のラベルと同じ。'C' は、'S'(Short)と同じになります。 354 * 355 * 「スペース+%+記号」が無ければ、通常のラベルと同じ処理を行います。 356 * つまり、このメソッドは、getLabel(String) より、ほんの少し処理時間を稼ぐために用意しました。 357 * なので、一応、内部からしか呼ばない事とし、private にしておきます。 358 * 359 * @og.rev 6.3.8.4 (2015/10/09) XXXX %S などの対応。getLabel(String) は汎用過ぎるので、少し分ける。 360 * @og.rev 6.3.9.0 (2015/11/06) switch 文の2つの case のために同じコードを使用している(findbugs) 361 * @og.rev 7.2.9.0 (2020/10/12) getRawShortLabelで、null時は key を返します。 362 * @og.rev 7.2.9.4 (2020/11/20) spotbugs:switch 文の2つの case のために同じコードを使用しているメソッド 363 * @og.rev 8.5.5.1 (2024/02/29) switch式の使用 364 * 365 * @param key ラベルキー 366 * 367 * @return リソースに応じたラベル文字列(無ければ ラベルキー) 368 */ 369 // 8.5.4.2 (2024/01/12) PMD 7.0.0 UnusedPrivateMethod … makeLabelArray 内のラムダで使用している。 370 private String getExtLabel( final String key ) { // NOPMD 371 final String val ; 372 373 final int ad = key.indexOf( " %" ); 374 if( ad < 0 ) { 375 val = getLabel( key ); 376 } 377 else if( ad+2 <= key.length() ) { // " %" の後ろの文字が存在しない場合 378 val = getLabel( key.substring( 0,ad ) ); 379 } 380 else { 381 final String tmpKey = key.substring( 0,ad ); 382 // 6.3.9.0 (2015/11/06) switch 文の2つの case のために同じコードを使用している(findbugs) 383 // 8.5.5.1 (2024/02/29) switch式の使用 384// switch( key.charAt( ad+2 ) ) { 385// case 'S': 386// case 'C': val = getShortLabel( tmpKey ); break; // 6.3.9.0 (2015/11/06) findbugs対応 387// case 'T': val = getLongLabel( tmpKey ); break; 388// case 'D': val = getDescription( tmpKey ); break; 389// case 'R': val = getRawShortLabel( tmpKey,true ); break; // 7.2.9.0 (2020/10/12) 390// default : val = getLabel( tmpKey ); break; 391// } 392 val = switch( key.charAt( ad+2 ) ) { 393 case 'S','C' -> getShortLabel( tmpKey ); // 6.3.9.0 (2015/11/06) findbugs対応 394 case 'T' -> getLongLabel( tmpKey ); 395 case 'D' -> getDescription( tmpKey ); 396 case 'R' -> getRawShortLabel( tmpKey,true ); // 7.2.9.0 (2020/10/12) 397 default -> getLabel( tmpKey ); 398 }; 399 } 400 return val; 401 } 402 403 /** 404 * ラベルリソースの引数で、#XXXXの変換で、カラム名が複数指定されている場合の対応を行います。 405 * 406 * 一つの引数に、#CLM,LANG,KBSAKU 等の項目名が複数指定指定された場合に、 407 * それぞれを解析してラベルに戻します。 408 * 該当するラベルが存在しない場合は、そのままの値を返します。 409 * 返される文字列配列は、元の引数とは異なる新しい文字列配列で返されます。 410 * 411 * @og.rev 6.1.0.0 (2014/12/26) #XXXXの変換で、カラム名が複数指定されている場合の対応 412 * @og.rev 6.3.8.4 (2015/10/09) #XXXX %S などの対応。getLabel(String) は汎用過ぎるので、少し分ける。 413 * @og.rev 6.4.1.1 (2016/01/16) PMD refactoring. Java8 ラムダ式を使用して、大幅書き直し。 414 * @og.rev 7.0.4.2 (2019/06/17) # のみの場合は、特別に、# を返すように対応。 415 * 416 * @param args メッセージの配列 417 * 418 * @return ラベル置換後の新しい文字列配列 419 */ 420 private String[] makeLabelArray( final String[] args ) { 421 final int size = args.length; 422 final String[] msgArgs = new String[size]; 423 424 for( int i=0; i<size; i++ ) { 425 final String arg = args[i] ; 426 if( StringUtil.startsChar( arg , '#' ) && arg.length() > 1 ) { // 7.0.4.2 (2019/06/17) 427 // 6.4.1.1 (2016/01/16) PMD refactoring. Avoid instantiating new objects inside loops 428 msgArgs[i] = Stream.of( StringUtil.csv2Array( arg.substring( 1 ) ) ) 429 .map( lbl -> getExtLabel( lbl ) ) 430 .collect( Collectors.joining( "," ) ); 431 } 432 else { 433 msgArgs[i] = arg ; 434 } 435 } 436 return msgArgs ; 437 } 438 439 /** 440 * ラベルリソースから、ラベル(短)を返します。 441 * 引数の言語コードに応じたリソースが登録されていない場合は、 442 * 引数のラベルキーそのまま返します。 443 * 444 * @og.rev 4.3.3.0 (2008/10/01) 新規作成 445 * @og.rev 6.3.9.0 (2015/11/06) labelLoader.getLabelDataは、nullを返しません。 446 * 447 * @param key ラベルキー 448 * 449 * @return リソースに応じたラベル文字列(無ければ ラベルキー) 450 */ 451 public String getShortLabel( final String key ) { 452 final LabelData lblData = labelLoader.getLabelData( key ); 453 // 6.4.1.1 (2016/01/16) PMD refactoring. A method should have only one exit point, and that should be the last statement in the method 454 // 反転注意 455 final String rtn = lblData.getShortLabel(); 456 457 return rtn == null ? key : rtn ; // なければ key を返す 458 } 459 460 /** 461 * ラベルリソースから、ラベル(長)を返します。 462 * 概要説明が存在する場合は、ツールチップに概要説明が 463 * 表示されます。 464 * 引数の言語コードに応じたリソースが登録されていない場合は、 465 * 引数のラベルキーそのまま返します。 466 * 467 * @og.rev 6.3.8.4 (2015/10/09) #XXXX %S などの対応。getLabel(String) は汎用過ぎるので、少し分ける。 468 * @og.rev 6.3.9.0 (2015/11/06) labelLoader.getLabelDataは、nullを返しません。 469 * 470 * @param key ラベルキー 471 * 472 * @return リソースに応じたラベル(長)文字列(無ければ ラベルキー) 473 */ 474 public String getLongLabel( final String key ) { 475 final LabelData lblData = labelLoader.getLabelData( key ); 476 // 6.4.1.1 (2016/01/16) PMD refactoring. A method should have only one exit point, and that should be the last statement in the method 477 // 反転注意 478 final String rtn = lblData.getLongLabel(); 479 480 return rtn == null ? key : rtn ; // なければ key を返す 481 } 482 483 /** 484 * ラベルリソースから、ラベル(長)ををそのままの形で返します。 485 * (discription等を付けない) 486 * 表示されます。 487 * 引数の言語コードに応じたリソースが登録されていない場合は、 488 * 引数のラベルキーそのまま返します。 489 * 490 * @og.rev 7.2.9.0 (2020/10/12) 新規追加 491 * 492 * @param key ラベルキー 493 * 494 * @return リソースに応じたラベル(長)そのままの文字列(無ければ ラベルキー) 495 * @og.rtnNotNull 496 */ 497 public String getRawLongLabel( final String key ) { 498 final LabelData lblData = labelLoader.getLabelData( key ); 499 500 return lblData.getRawLongLabel(); 501 } 502 503 /** 504 * ラベルオブジェクトの名称(短)をspanタグを付けない状態で返します。 505 * SNAMEが未設定の場合は、LNAME が返されます。 506 * 引数の言語コードに応じたリソースが登録されていない場合は、 507 * 引数のラベルキーそのまま返します。 508 * 509 * @og.rev 6.3.8.4 (2015/10/09) #XXXX %S などの対応。getLabel(String) は汎用過ぎるので、少し分ける。 510 * @og.rev 6.3.9.0 (2015/11/06) labelLoader.getLabelDataは、nullを返しません。 511 * @og.rev 7.0.7.0 (2019/12/13) args パラメータ配列(可変長引数)を追加します。 512 * @og.rev 7.2.9.0 (2020/10/12) args パラメータ配列(可変長引数)廃止(旧メソッド復活) 513 * 514 * @param key ラベルキー 515 * @param useKey null時にキーを返す場合は、true , 空文字を返す場合は、false 516 * 517 * @return リソースに応じたラベル(短)文字列(無ければ ラベルキー) 518 */ 519 public String getRawShortLabel( final String key , final boolean useKey ) { 520 final LabelData lblData = labelLoader.getLabelData( key ); 521 522 return lblData.getRawShortLabel( useKey ? key : "" ); 523 } 524 525 /** 526 * ラベルリソースから、概要説明を返します。 527 * {0},{1}...の置換えを行います。 528 * キーのデータが存在しない場合はnullを返します。 529 * ただし、パラメータのデータがあれば、それを返します。 530 * 531 * @og.rev 4.3.7.6 (2009/07/15) 新規作成 532 * @og.rev 6.1.0.0 (2014/12/26) #XXXXの変換で、カラム名が複数指定されている場合の対応 533 * @og.rev 6.3.9.0 (2015/11/06) labelLoader.getLabelDataは、nullを返しません。 534 * @og.rev 7.0.7.0 (2019/12/13) #getDescription( String ) と統合します。 535 * 536 * @param key ラベルキー 537 * @param args パラメータ配列(可変長引数) 538 * 539 * @return リソースに応じた概要説明(無ければ null) 540 */ 541 public String getDescription( final String key,final String... args ) { // 6.6.0.0 (2016/12/01) 542 final LabelData lblData = labelLoader.getLabelData( key ); 543 544 final String msgdesc ; 545 if( args == null || args.length == 0 ){ 546 msgdesc = lblData.getDescription(); 547 } 548 else { 549 // 6.1.0.0 (2014/12/26) getLabel( String ,String[] ) と同様に複数ラベル対応 550 final String[] msgArgs = makeLabelArray( args ); 551 552 // 6.1.0.0 (2014/12/26) LabelData が存在しなかった場合の処理 553 msgdesc = lblData.getDescription( msgArgs ); 554 } 555 556 return msgdesc == null ? key : msgdesc ; // なければ key を返す 557 } 558 559 /** 560 * メッセージリソースからErrMsgオブジェクトで指定されたメッセージを返します。 561 * 562 * このエラーメッセージは、リソースで選ばれたロケール毎のメッセージに、 563 * MessageFormat#format でフォーマットする事により作成されます。 564 * エラーメッセージがリソースに存在しない場合はエラーコードを返します。 565 * 566 * @og.rev 4.0.0.0 (2004/12/31) 新規追加 567 * @og.rev 4.0.0.0 (2007/10/18) メッセージリソースとの統合化 568 * 569 * @param errMsgObj ErrMsgオブジェクト 570 * 571 * @return エラーメッセージ(無ければ ErrMsgオブジェクトの toString() ) 572 */ 573 public String getLabel( final ErrMsg errMsgObj ) { 574 return getLabel( errMsgObj.getId(),errMsgObj.getArgs() ); 575 } 576 577 /** 578 * メッセージリソースからErrMsgオブジェクトで指定されたショートメッセージを返します。 579 * 580 * このエラーメッセージは、リソースで選ばれたロケール毎のメッセージに、 581 * MessageFormat#format でフォーマットする事により作成されます。 582 * エラーメッセージがリソースに存在しない場合はエラーコードを返します。 583 * 584 * @og.rev 7.0.7.0 (2019/12/13) 新規追加 585 * @og.rev 7.2.9.0 (2020/10/12) 引数を分解して、直接処理します。…ついでにメソッド名変更 586 * 587 * @param errMsgObj ErrMsgオブジェクト 588 * 589 * @return エラーメッセージ(無ければ ErrMsgオブジェクトの toString() ) 590 */ 591 public String getShortErrorMsg( final ErrMsg errMsgObj ) { 592 final String key = errMsgObj.getId(); 593 final String[] args = errMsgObj.getArgs(); 594 595 final LabelData lblData = labelLoader.getLabelData( key ); 596 597 final String msglbl ; 598 if( args == null || args.length == 0 ){ 599 msglbl = lblData.getRawShortLabel(); 600 } 601 else { 602 // 6.1.0.0 (2014/12/26) メソッド化 603 final String[] msgArgs = makeLabelArray( args ); // 6.1.0.0 (2014/12/26) メソッド化 604 605 // 6.3.9.0 (2015/11/06) labelLoader.getLabelDataは、nullを返しません。 606 msglbl = lblData.getShortMessage( msgArgs ); 607 } 608 609 return msglbl == null ? key : msglbl ; // なければ key を返す 610 } 611 612 /** 613 * ErrMsgオブジェクトの内容を元に、ラベルリソースから概要説明を返します。 614 * キーのデータが存在しない場合はnullを返します。 615 * 616 * @og.rev 4.3.7.6 (2009/07/15) 新規作成 617 * 618 * @param errMsgObj ErrMsgオブジェクト 619 * 620 * @return エラーメッセージ(キーが無ければnull) 621 */ 622 public String getDescription( final ErrMsg errMsgObj ) { 623 return getDescription( errMsgObj.getId(),errMsgObj.getArgs() ); 624 } 625 626 /** 627 * ラベルキーに対応する、LabelDataオブジェクトを返します。 628 * 629 * @og.rev 4.0.0.0 (2005/01/31) 新規作成 630 * @og.rev 6.3.9.0 (2015/11/06) labelLoader.getLabelDataは、nullを返しません。 631 * 632 * @param key ラベルキー 633 * 634 * @return LabelDataオブジェクト 635 * @og.rtnNotNull 636 */ 637 public LabelData getLabelData( final String key ) { 638 return labelLoader.getLabelData( key ); 639 } 640 641 /** 642 * コードキーに対応する、CodeDataオブジェクトを返します。 643 * 644 * @param key コードキー 645 * 646 * @return CodeDataオブジェクト(無ければ null) 647 */ 648 public CodeData getCodeData( final String key ) { 649 return codeLoader.getCodeData( key ); 650 } 651 652 /** 653 * コードリソースからコード文字列を返します。 654 * 引数にQUERYを渡すことで、DBから、動的にコードリソースを作成できます。 655 * 656 * @og.rev 5.4.2.2 (2011/12/14) 新規追加。 657 * 658 * @param key コードキー 659 * @param query 検索SQL(引数に、? を一つ持つ) 660 * 661 * @return コードデータオブジェクト(無ければ null) 662 */ 663 public CodeData getCodeData( final String key,final String query ) { 664 return codeLoader.getCodeData( key,query ); 665 } 666 667 /** 668 * ログインユーザーで使用する画面オブジェクトを、UserInfoにセットします。 669 * 各、UserInfo は、自分自身が使用する 画面オブジェクトのみを管理することで、 670 * 画面アクセス有無を、すばやく検索することが可能になります。 671 * 672 * @og.rev 3.1.0.1 (2003/03/26) GUIInfo のキー順サポートの為に、引数追加。 673 * @og.rev 4.0.0.0 (2005/01/31) 使用画面のMap を UserInfo にセットします。 674 * @og.rev 4.3.0.0 (2008/07/04) ロールモードマルチ対応 675 * @og.rev 5.2.0.0 (2010/09/01) アクセス禁止アドレスによる不正アクセス防止機能追加 676 * @og.rev 6.4.3.4 (2016/03/11) forループを、removeAll メソッドに置き換えます。 677 * @og.rev 6.4.4.2 (2016/04/01) guiMap.values() では、GUIInfo だが、remove するのは、gui.getAddress() の値。 678 * @og.rev 7.1.0.0 (2020/01/27) LabelDataを直接呼び出します。 679 * 680 * @param user 指定のユーザーロールに対応する画面だけをMapにセットする。 681 */ 682 public void makeGUIInfos( final UserInfo user ) { 683 final GUIData[] guiDatas = guiLoader.getAllData(); 684 685 // guikey に対してユニークになるように Map に追加します。後登録が優先されます。 686 final Map<String,GUIInfo> guiMap = new HashMap<>(); 687 final Set<String> forbidAddrSet = new HashSet<>(); 688 int size = guiDatas.length; 689 for( int i=0; i<size; i++ ) { 690 final GUIData gui = guiDatas[i]; 691 final byte bitMode = user.getAccessBitMode( gui.getRoleMode() ); 692 if( bitMode > 0 ) { 693 final String guikey = gui.getGuiKey(); 694 final LabelData labelData = labelLoader.getLabelData( gui.getLabelClm() ); // 7.1.0.0 (2020/01/27) 695 guiMap.put( guikey,new GUIInfo( gui,labelData,bitMode ) ); 696 } 697 // 5.2.0.0 (2010/09/01) アクセス禁止アドレスによる不正アクセス防止機能追加 698 else { 699 final String addr = gui.getAddress(); 700 if( addr.indexOf( '/' ) < 0 ) { 701 forbidAddrSet.add( addr ); 702 } 703 } 704 } 705 706 // もし、禁止リストの中に画面ID違いで許可リストと同じアドレスが 707 // 含まれている場合は、禁止リスト中から該当のアドレスを削除する。 708 // 6.4.3.4 (2016/03/11) forループを、removeAll メソッドに置き換えます。 709 // 6.4.4.2 (2016/04/01) guiMap.values() では、GUIInfo だが、remove するのは、gui.getAddress() の値。 710 guiMap.forEach( (id,gui) -> forbidAddrSet.remove( gui.getAddress() ) ); 711 712 // GUIInfo をその順番(SEQNO順)でソートし直します。SYSTEM_ID や、KBSAKU の影響を排除します。 713// final GUIInfo[] guiInfos = guiMap.values().toArray( new GUIInfo[ guiMap.size() ] ) ; 714 final GUIInfo[] guiInfos = guiMap.values().toArray( new GUIInfo[0] ) ; // 8.5.4.2 (2024/01/12) PMD 7.0.0 OptimizableToArrayCall 対応 715 Arrays.sort( guiInfos ); 716 final Map<String,GUIInfo> sortMap = new LinkedHashMap<>(); 717 size = guiInfos.length; 718 for( int i=0; i<size; i++ ) { 719 final GUIInfo guiInfo = guiInfos[i]; 720 final String guikey = guiInfo.getKey(); 721 sortMap.put( guikey,guiInfo ); 722 } 723 724 user.setGUIMap( sortMap, forbidAddrSet ); 725 } 726 727 /** 728 * 指定されたクエリを発行し、ラベルマップを作成します。 729 * 730 * @og.rev 4.3.4.0 (2008/12/01) 新規作成 731 * @og.rev 6.4.0.5 (2016/01/09) useLabelMap="true" 時のSQL文の実行は、dbid を使用して行う。 732 * 733 * @param query ラベルマップを作成するクエリ 734 * @param dbid 接続先ID 735 * 736 * @return ラベルマップ 737 * @see org.opengion.hayabusa.resource.LabelDataLoader#getLabelMap( String,String ) 738 */ 739 public Map<String, LabelData> getLabelMap( final String query , final String dbid ) { 740 return labelLoader.getLabelMap( query , dbid ); 741 } 742 743 /** 744 * リソースマネージャーをキーに基づいて部分クリアします。 745 * ここでは、部分クリアなため、GUIData に関しては、処理されません。 746 * また、存在しないキーを指定されたリソースは、何も処理されません。 747 * 748 * @og.rev 5.4.3.4 (2012/01/12) labelPool の削除追加 749 * @og.rev 6.4.3.3 (2016/03/04) ConcurrentHashMap の not null制限のチェック追加 750 * @og.rev 6.9.0.1 (2018/02/05) どのシステムIDのリソースがクリアされたかを表示します。 751 * 752 * @param key カラムのキー 753 */ 754 public void clear( final String key ) { 755 // 6.4.3.3 (2016/03/04) ConcurrentHashMap の not null制限 756 if( key != null ) { 757 columnLoader.clear( key ); 758 codeLoader.clear( key ); 759 labelLoader.clear( key ); 760 columnPool.remove( key ); // 8.5.6.0 (2024/02/29) ここではキャッシュしない 761 } 762 } 763 764 /** 765 * GUI情報をクリアします。 766 * ここでは、関連するラベル、コードリソースの部分クリアも行います。 767 * GUI情報は、シーケンスに管理しているため、この処理1回ごとに、 768 * GUIData を全件再読み込みを行いますので、ご注意ください。 769 * 770 */ 771 public void guiClear() { 772 // 8.5.4.2 (2024/01/12) PMD 7.0.0 ForLoopCanBeForeach 773// final GUIData[] gui = guiLoader.getAllData(); 774// for( int i=0; i<gui.length; i++ ) { 775// final String key = gui[i].getGuiKey(); 776// labelLoader.clear( key ); 777// } 778 for( final GUIData gui : guiLoader.getAllData() ) { 779 labelLoader.clear( gui.getGuiKey() ); // key 780 } 781 codeLoader.clear( "CLASSIFY" ); 782 guiLoader.clear(); 783 } 784 785 /** 786 * リソースマネージャーをクリア(初期化)します。 787 * 788 * @og.rev 5.4.3.4 (2012/01/12) labelPool の削除追加 789 * 790 */ 791 public void clear() { 792 columnLoader.clear(); 793 codeLoader.clear(); 794 labelLoader.clear(); 795 guiLoader.clear(); 796 columnPool.clear(); // 8.5.6.0 (2024/02/29) ここではキャッシュしない 797 } 798}