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 */
016 package org.opengion.hayabusa.resource;
017
018 import org.opengion.hayabusa.common.HybsSystem;
019 import org.opengion.fukurou.util.ApplicationInfo;
020 import org.opengion.fukurou.db.DBUtil;
021
022 import java.util.Map;
023 import java.util.HashMap;
024 import java.util.LinkedHashMap ;
025 import java.util.WeakHashMap ;
026 import java.util.Collections ;
027
028 /**
029 * コードオブジェクトを作?する??タロードクラスです?
030 * systemId と lang に対応したコードオブジェクトを作?します?
031 *
032 * コードオブジェクト???目(CLM)に対して、?のコー?CODE)を持って?す?
033 * こ??のコードを表示?持つことで、?ル?ンメニュー等?表示??します?
034 *
035 * コードオブジェクトを作?する場合?、同??目・コードで、作?区?KBSAKU)違いの場合??
036 * ?大きな作?区?持つコードを使用します?
037 * 作?区?KBSAKU)は、他?リソースと異なり?同??目・コード単位に設定すべきです?
038 * これは??常は?単位に作?区?持つべきところを?コード単位でしか
039 * 持てな?ータベ?スの設計になって?為です?アプリケーション側で設定条件?
040 * きちんと管?れ?、作?区?使用できますが、?にはお奨めできません?
041 * 作?区?KBSAKU)='0' の??タは、?スタリソースとして、エンジンとともに
042 * 配?れるリソースになります?
043 *
044 * 読み込みフラグ(FGLOAD)は、使用しません?
045 * コードリソースに関しては、シス?起動時に、すべてのコードリソースをエンジン?
046 * に取り込みます?ただし?リソースのキャ?ュに、WeakHashMap クラスを使用して?ため?
047 * メモリオーバ?時には、クリアされるため?単独での読み取りも行います?
048 * SYSTEM_ID='**' は、?通リソースです?
049 * これは、シス?間で共通に使用されるリソース??を登録しておきます?
050 *
051 * @og.rev 4.0.0.0 (2004/12/31) 新規作?
052 * @og.group リソース管?
053 *
054 * @version 4.0
055 * @author Kazuhiko Hasegawa
056 * @since JDK5.0,
057 */
058 final class CodeDataLoader {
059 // リソースの接続?を?取得します?
060 private final String DBID = HybsSystem.sys( "RESOURCE_DBID" );
061
062 /** ??リソースの初期?読み込みのクエリー */
063 // キーブレイクで、SYSTEM_ID 違いは、まとめて処?る為、最初に ORDER BY しておく?があります?
064 //public static final String QUERY = "select CLM,CODE,'','',CODELVL,CODEGRP,CODE_PARAM,ROLES,SYSTEM_ID,KBSAKU" // 4.0.0.0(2007/10/17)
065 // public static final String QUERY = "select CLM,CODE,'','',CODELVL,CODEGRP,CODE_PARAM,ROLES,SYSTEM_ID,KBSAKU,''" // 4.3.8.0 (2009/08/01)
066 // + " from GEA04 where SYSTEM_ID in ( ?,'**') and FGJ='1'"
067 // + " order by SYSTEM_ID,KBSAKU,CLM,SEQNO,CODE" ;
068 // 5.1.9.0 (2010/08/01) order by 変更
069 public static final String QUERY = "select CLM,CODE,'','',CODELVL,CODEGRP,CODE_PARAM,ROLES,SYSTEM_ID,KBSAKU,''" // 5.1.9.0 (2010/08/01)
070 + " from GEA04 where SYSTEM_ID in ( ?,'**') and FGJ='1'"
071 + " order by SYSTEM_ID,KBSAKU,CLM,SEQNO,CODELVL,CODE" ;
072
073 /** ??リソースの個別読み込み時?クエリー */
074 //public static final String QUERY2 = "select CLM,CODE,'','',CODELVL,CODEGRP,CODE_PARAM,ROLES,SYSTEM_ID,KBSAKU" // 4.0.0.0(2007/10/17)
075 // public static final String QUERY2 = "select CLM,CODE,'','',CODELVL,CODEGRP,CODE_PARAM,ROLES,SYSTEM_ID,KBSAKU,''" // 4.3.8.0 (2009/08/01)
076 // + " from GEA04 where SYSTEM_ID in ( ?,'**') and FGJ='1' and CLM=?"
077 // + " order by SYSTEM_ID,KBSAKU,CLM,SEQNO,CODE" ;
078 // 5.1.9.0 (2010/08/01) order by 変更
079 public static final String QUERY2 = "select CLM,CODE,'','',CODELVL,CODEGRP,CODE_PARAM,ROLES,SYSTEM_ID,KBSAKU,''" // 5.1.9.0 (2010/08/01)
080 + " from GEA04 where SYSTEM_ID in ( ?,'**') and FGJ='1' and CLM=?"
081 + " order by SYSTEM_ID,KBSAKU,CLM,SEQNO,CODELVL,CODE" ;
082
083 private final Map<String,CodeData> pool = Collections.synchronizedMap( new WeakHashMap<String,CodeData>() ); // キャ?ュ用プ?ル
084 private final String SYSTEM_ID ; // シス?ID
085 // private final String LANG ; // ??
086
087 /** コネクションにアプリケーション??を追記するかど???*/
088 public static final boolean USE_DB_APPLICATION_INFO = HybsSystem.sysBool( "USE_DB_APPLICATION_INFO" ) ;
089
090 // 3.8.7.0 (2006/12/15) アクセスログ取得?為,ApplicationInfoオブジェクトを設?
091 private final ApplicationInfo appInfo;
092
093 private final LabelDataLoader LABEL_LOADER; // 見直し?!!
094
095 /**
096 * lang 毎に ファクトリオブジェクトを作?します?
097 *
098 * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得?為,ApplicationInfoオブジェクトを設?
099 *
100 * @param systemId シス?ID
101 * @param initLoad リソース??タの先読み可否(true:先読みする)
102 * @param lLoader ラベル??タロー??
103 */
104 // CodeDataLoader( final String systemId,final String lang,final boolean initLoad ) {
105 CodeDataLoader( final String systemId,final boolean initLoad,final LabelDataLoader lLoader) {
106 SYSTEM_ID = systemId;
107 // LANG = lang;
108 LABEL_LOADER = lLoader;
109
110 // 3.8.7.0 (2006/12/15) アクセスログ取得?為,ApplicationInfoオブジェクトを設?
111 if( USE_DB_APPLICATION_INFO ) {
112 appInfo = new ApplicationInfo();
113 // ユーザーID,IPアドレス,ホスト名
114 appInfo.setClientInfo( SYSTEM_ID,HybsSystem.HOST_ADRS,HybsSystem.HOST_NAME );
115 // 画面ID,操?プログラ?D
116 appInfo.setModuleInfo( "CodeDataLoader",null,null );
117 }
118 else {
119 appInfo = null;
120 }
121
122 // ApplicationInfo の設定が終わってから実行します?
123 if( initLoad ) { loadDBResource(); }
124 }
125
126 /**
127 * ??リソースより コードデータを取得?設定します?
128 *
129 * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得?為,ApplicationInfoオブジェクトを設?
130 * @og.rev 4.3.8.0 (2009/08/01) rawShortLabel追?
131 */
132 private void loadDBResource() {
133 // String[] args = new String[] { LANG,SYSTEM_ID };
134 String[] args = new String[] { SYSTEM_ID };
135
136 String[][] vals = DBUtil.dbExecute( QUERY,args,appInfo,DBID );
137
138 Map<String,Map<String,String[]>> clmMap = new HashMap<String,Map<String,String[]>>();
139 int len = vals.length;
140 String bkClm = null; // キーブレイク
141 String bkSystem = null;
142 String bkKbsaku = null;
143 // 以下?処??、SYSTEM_ID違いを塊で処?ます?(混在させません?
144 Map<String,String[]> codeMap = null;
145 for( int i=0; i<len; i++ ) {
146 String clm = vals[i][CodeData.CLM];
147 String code = vals[i][CodeData.CODE];
148 String systemId = vals[i][CodeData.SYSTEM_ID];
149 String kbsaku = vals[i][CodeData.KBSAKU];
150 // if( bkClm == null || !bkClm.equals( clm ) ) {
151 if( bkClm == null || !bkClm.equals( clm ) || !bkSystem.equals(systemId) || !bkKbsaku.equals(kbsaku) ) {
152 codeMap = new LinkedHashMap<String,String[]>();
153 clmMap.put( clm,codeMap );
154 bkClm = clm;
155 bkSystem = systemId;
156 bkKbsaku = kbsaku;
157 }
158
159 String lkey = clm+"."+code; // ?つけ?
160 vals[i][CodeData.LNAME] = LABEL_LOADER.getLabelData(lkey).getLongLabel();
161 vals[i][CodeData.SNAME] = LABEL_LOADER.getLabelData(lkey).getShortLabel();
162 vals[i][CodeData.RSNAME] = LABEL_LOADER.getLabelData(lkey).getRawShortLabel(); // 4.3.8.0 (2009/08/01) spanが付かな?前短
163
164 codeMap.put( code,vals[i] );
165 }
166
167 String[] clmKeys = clmMap.keySet().toArray( new String[clmMap.size()] );
168 int size = clmKeys.length;
169 for( int i=0; i<size; i++ ) {
170 String clm = clmKeys[i];
171 codeMap = clmMap.get( clm );
172
173 pool.put( clm,new CodeData( clm,codeMap ) );
174 }
175
176 System.out.println( " CodeDataLoader [" + size + "] loaded" );
177 }
178
179 /**
180 * CodeData オブジェクトを取得します?
181 * 作?したCodeDataオブジェクト???部にプ?ルしておき?同じリソース要求が
182 * あったとき???ールの CodeDataを返します?
183 *
184 * @og.rev 4.3.8.0 (2009/08/01) rawShortLabel追?
185 *
186 * @param key コード?キー
187 *
188 * @return CodeData オブジェク?
189 */
190 public CodeData getCodeData( final String key ) {
191 CodeData codeData = pool.get( key ) ;
192
193 if( codeData == null ) {
194 // String[] args = new String[] { LANG,SYSTEM_ID,key };
195 String[] args = new String[] { SYSTEM_ID,key };
196 String[][] vals = DBUtil.dbExecute( QUERY2,args,appInfo,DBID );
197
198 int len = vals.length;
199 String bkSystem = null; // キーブレイク
200 String bkKbsaku = null;
201 // 以下?処??、SYSTEM_ID違いを塊で処?ます?(混在させません?
202 Map<String,String[]> codeMap = null;
203 for( int i=0; i<len; i++ ) {
204 String systemId = vals[i][CodeData.SYSTEM_ID];
205 String code = vals[i][CodeData.CODE];
206 String kbsaku = vals[i][CodeData.KBSAKU];
207 // if( bkSystem == null || !bkSystem.equals( systemId ) ) {
208 if( bkSystem == null || !bkSystem.equals( systemId ) || !bkKbsaku.equals(kbsaku) ) {
209 codeMap = new LinkedHashMap<String,String[]>();
210 bkSystem = systemId;
211 bkKbsaku = kbsaku;
212 }
213
214 String lkey = key+"."+code; // ?つけ?
215 vals[i][CodeData.LNAME] = LABEL_LOADER.getLabelData(lkey).getLongLabel();
216 vals[i][CodeData.SNAME] = LABEL_LOADER.getLabelData(lkey).getShortLabel();
217 vals[i][CodeData.RSNAME] = LABEL_LOADER.getLabelData(lkey).getRawShortLabel(); // 4.3.8.0 (2009/08/01) spanが付かな?前短
218
219 codeMap.put( code,vals[i] );
220 }
221
222 if( codeMap != null ) {
223 codeData = new CodeData( key,codeMap );
224 pool.put( key,codeData );
225 }
226 }
227 return codeData ;
228 }
229
230 /**
231 * CodeData オブジェクトを取得します?
232 * 作?したCodeDataオブジェクト???部にプ?ルしておき?同じリソース要求が
233 * あったとき???ールの CodeDataを返します?
234 *
235 * 引数にQUERYを渡すことで、DBから、動?コードリソースを作?できます?
236 * 引数の?は、CodeData で定義して? CLM,CODE,LNAME,SNAME の?のままです?
237 * QUERY には、key を引数にとる?があります?つまり?WHERE CLM = ? の様な記述が?です?
238 *
239 * @og.rev 5.4.2.2 (2011/12/14) 新規追??
240 *
241 * @param key コード?キー
242 * @param query 検索SQL(引数に? を?持つ)
243 *
244 * @return CodeData オブジェク?
245 */
246 public CodeData getCodeData( final String key,final String query ) {
247 CodeData codeData = pool.get( key ) ;
248
249 if( codeData == null ) {
250 String[] args = new String[] { key };
251 String[][] vals = DBUtil.dbExecute( query,args,appInfo,DBID );
252
253 int len = vals.length;
254 Map<String,String[]> codeMap = new LinkedHashMap<String,String[]>();
255 for( int i=0; i<len; i++ ) {
256 String[] cdVals = new String[CodeData.MAX_LENGTH]; // 空の配?を毎回作?
257
258 String code = vals[i][CodeData.CODE];
259
260 cdVals[CodeData.CLM] = key ;
261 cdVals[CodeData.CODE] = code;
262 cdVals[CodeData.LNAME] = vals[i][CodeData.LNAME];
263 cdVals[CodeData.SNAME] = vals[i][CodeData.SNAME];
264
265 codeMap.put( code,cdVals );
266 }
267
268 if( ! codeMap.isEmpty() ) {
269 codeData = new CodeData( key,codeMap );
270 pool.put( key,codeData );
271 }
272 }
273 return codeData ;
274 }
275
276 /**
277 * CodeData オブジェクト?キャ?ュを?別にクリアします?
278 * リソース??タの更新など、???更新時に、すべてのキャ?ュ?
279 * 破?る?ではなく?????み破?きる機?です?
280 *
281 * @og.rev 4.0.2.0 (2007/12/25) コードリソースクリア時に対応するラベルリソースもクリアする?
282 *
283 * @param key コード?キー
284 */
285 public void clear( final String key ) {
286
287 // 4.0.2.0 (2007/12/25)
288 CodeData cdata = pool.remove( key );
289 if( cdata != null ) {
290 String clm = cdata.getColumn();
291 for( int i=0; i<cdata.getSize(); i++ ) {
292 LABEL_LOADER.clear( clm + '.' + cdata.getCodeKey( i ) );
293 }
294 }
295 }
296
297 /**
298 * CodeData オブジェクト?キャ?ュをクリアして、?作?します?
299 *
300 */
301 public void clear() {
302 pool.clear();
303 }
304 }