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 public static final String QUERY = "select CLM,CODE,'','',CODELVL,CODEGRP,CODE_PARAM,ROLES,SYSTEM_ID,KBSAKU,'',''" // 5.6.8.2 (2013/09/20)
071 + " from GEA04 where SYSTEM_ID in ( ?,'**') and FGJ='1'"
072 + " order by SYSTEM_ID,KBSAKU,CLM,SEQNO,CODELVL,CODE" ;
073
074 /** ??リソースの個別読み込み時?クエリー */
075 //public static final String QUERY2 = "select CLM,CODE,'','',CODELVL,CODEGRP,CODE_PARAM,ROLES,SYSTEM_ID,KBSAKU" // 4.0.0.0(2007/10/17)
076 // public static final String QUERY2 = "select CLM,CODE,'','',CODELVL,CODEGRP,CODE_PARAM,ROLES,SYSTEM_ID,KBSAKU,''" // 4.3.8.0 (2009/08/01)
077 // + " from GEA04 where SYSTEM_ID in ( ?,'**') and FGJ='1' and CLM=?"
078 // + " order by SYSTEM_ID,KBSAKU,CLM,SEQNO,CODE" ;
079 // 5.1.9.0 (2010/08/01) order by 変更
080 // public static final String QUERY2 = "select CLM,CODE,'','',CODELVL,CODEGRP,CODE_PARAM,ROLES,SYSTEM_ID,KBSAKU,''" // 5.1.9.0 (2010/08/01)
081 public static final String QUERY2 = "select CLM,CODE,'','',CODELVL,CODEGRP,CODE_PARAM,ROLES,SYSTEM_ID,KBSAKU,'',''" // 5.6.8.2 (2013/09/20)
082 + " from GEA04 where SYSTEM_ID in ( ?,'**') and FGJ='1' and CLM=?"
083 + " order by SYSTEM_ID,KBSAKU,CLM,SEQNO,CODELVL,CODE" ;
084
085 private final Map<String,CodeData> pool = Collections.synchronizedMap( new WeakHashMap<String,CodeData>() ); // キャ?ュ用プ?ル
086 private final String SYSTEM_ID ; // シス?ID
087 // private final String LANG ; // ??
088
089 /** コネクションにアプリケーション??を追記するかど???*/
090 public static final boolean USE_DB_APPLICATION_INFO = HybsSystem.sysBool( "USE_DB_APPLICATION_INFO" ) ;
091
092 // 3.8.7.0 (2006/12/15) アクセスログ取得?為,ApplicationInfoオブジェクトを設?
093 private final ApplicationInfo appInfo;
094
095 private final LabelDataLoader LABEL_LOADER; // 見直し?!!
096
097 /**
098 * lang 毎に ファクトリオブジェクトを作?します?
099 *
100 * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得?為,ApplicationInfoオブジェクトを設?
101 *
102 * @param systemId シス?ID
103 * @param initLoad リソース??タの先読み可否(true:先読みする)
104 * @param lLoader ラベル??タロー??
105 */
106 // CodeDataLoader( final String systemId,final String lang,final boolean initLoad ) {
107 CodeDataLoader( final String systemId,final boolean initLoad,final LabelDataLoader lLoader) {
108 SYSTEM_ID = systemId;
109 // LANG = lang;
110 LABEL_LOADER = lLoader;
111
112 // 3.8.7.0 (2006/12/15) アクセスログ取得?為,ApplicationInfoオブジェクトを設?
113 if( USE_DB_APPLICATION_INFO ) {
114 appInfo = new ApplicationInfo();
115 // ユーザーID,IPアドレス,ホスト名
116 appInfo.setClientInfo( SYSTEM_ID,HybsSystem.HOST_ADRS,HybsSystem.HOST_NAME );
117 // 画面ID,操?プログラ?D
118 appInfo.setModuleInfo( "CodeDataLoader",null,null );
119 }
120 else {
121 appInfo = null;
122 }
123
124 // ApplicationInfo の設定が終わってから実行します?
125 if( initLoad ) { loadDBResource(); }
126 }
127
128 /**
129 * ??リソースより コードデータを取得?設定します?
130 *
131 * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得?為,ApplicationInfoオブジェクトを設?
132 * @og.rev 4.3.8.0 (2009/08/01) rawShortLabel追?
133 * @og.rev 5.6.8.2 (2013/09/20) rawLongLabel対?
134 */
135 private void loadDBResource() {
136 // String[] args = new String[] { LANG,SYSTEM_ID };
137 String[] args = new String[] { SYSTEM_ID };
138
139 String[][] vals = DBUtil.dbExecute( QUERY,args,appInfo,DBID );
140
141 Map<String,Map<String,String[]>> clmMap = new HashMap<String,Map<String,String[]>>();
142 int len = vals.length;
143 String bkClm = null; // キーブレイク
144 String bkSystem = null;
145 String bkKbsaku = null;
146 // 以下?処??、SYSTEM_ID違いを塊で処?ます?(混在させません?
147 Map<String,String[]> codeMap = null;
148 for( int i=0; i<len; i++ ) {
149 String clm = vals[i][CodeData.CLM];
150 String code = vals[i][CodeData.CODE];
151 String systemId = vals[i][CodeData.SYSTEM_ID];
152 String kbsaku = vals[i][CodeData.KBSAKU];
153 // if( bkClm == null || !bkClm.equals( clm ) ) {
154 if( bkClm == null || !bkClm.equals( clm ) || !bkSystem.equals(systemId) || !bkKbsaku.equals(kbsaku) ) {
155 codeMap = new LinkedHashMap<String,String[]>();
156 clmMap.put( clm,codeMap );
157 bkClm = clm;
158 bkSystem = systemId;
159 bkKbsaku = kbsaku;
160 }
161
162 String lkey = clm+"."+code; // ?つけ?
163 vals[i][CodeData.LNAME] = LABEL_LOADER.getLabelData(lkey).getLongLabel();
164 vals[i][CodeData.SNAME] = LABEL_LOADER.getLabelData(lkey).getShortLabel();
165 vals[i][CodeData.RSNAME] = LABEL_LOADER.getLabelData(lkey).getRawShortLabel(); // 4.3.8.0 (2009/08/01) spanが付かな?前短
166 vals[i][CodeData.RLNAME] = LABEL_LOADER.getLabelData(lkey).getRawLongLabel(); // 5.6.8.2 (2013/09/01) ?して??前長
167
168 codeMap.put( code,vals[i] );
169 }
170
171 String[] clmKeys = clmMap.keySet().toArray( new String[clmMap.size()] );
172 int size = clmKeys.length;
173 for( int i=0; i<size; i++ ) {
174 String clm = clmKeys[i];
175 codeMap = clmMap.get( clm );
176
177 pool.put( clm,new CodeData( clm,codeMap ) );
178 }
179
180 System.out.println( " CodeDataLoader [" + size + "] loaded" );
181 }
182
183 /**
184 * CodeData オブジェクトを取得します?
185 * 作?したCodeDataオブジェクト???部にプ?ルしておき?同じリソース要求が
186 * あったとき???ールの CodeDataを返します?
187 *
188 * @og.rev 4.3.8.0 (2009/08/01) rawShortLabel追?
189 * @og.rev 5.6.8.2 (2013/09/20) rawLongLabel追?
190 *
191 * @param key コード?キー
192 *
193 * @return CodeData オブジェク?
194 */
195 public CodeData getCodeData( final String key ) {
196 CodeData codeData = pool.get( key ) ;
197
198 if( codeData == null ) {
199 // String[] args = new String[] { LANG,SYSTEM_ID,key };
200 String[] args = new String[] { SYSTEM_ID,key };
201 String[][] vals = DBUtil.dbExecute( QUERY2,args,appInfo,DBID );
202
203 int len = vals.length;
204 String bkSystem = null; // キーブレイク
205 String bkKbsaku = null;
206 // 以下?処??、SYSTEM_ID違いを塊で処?ます?(混在させません?
207 Map<String,String[]> codeMap = null;
208 for( int i=0; i<len; i++ ) {
209 String systemId = vals[i][CodeData.SYSTEM_ID];
210 String code = vals[i][CodeData.CODE];
211 String kbsaku = vals[i][CodeData.KBSAKU];
212 // if( bkSystem == null || !bkSystem.equals( systemId ) ) {
213 if( bkSystem == null || !bkSystem.equals( systemId ) || !bkKbsaku.equals(kbsaku) ) {
214 codeMap = new LinkedHashMap<String,String[]>();
215 bkSystem = systemId;
216 bkKbsaku = kbsaku;
217 }
218
219 String lkey = key+"."+code; // ?つけ?
220 vals[i][CodeData.LNAME] = LABEL_LOADER.getLabelData(lkey).getLongLabel();
221 vals[i][CodeData.SNAME] = LABEL_LOADER.getLabelData(lkey).getShortLabel();
222 vals[i][CodeData.RSNAME] = LABEL_LOADER.getLabelData(lkey).getRawShortLabel(); // 4.3.8.0 (2009/08/01) spanが付かな?前短
223 vals[i][CodeData.RLNAME] = LABEL_LOADER.getLabelData(lkey).getRawLongLabel(); // 5.6.8.2 (2013/09/20) ?して??前長
224
225 codeMap.put( code,vals[i] );
226 }
227
228 if( codeMap != null ) {
229 codeData = new CodeData( key,codeMap );
230 pool.put( key,codeData );
231 }
232 }
233 return codeData ;
234 }
235
236 /**
237 * CodeData オブジェクトを取得します?
238 * 作?したCodeDataオブジェクト???部にプ?ルしておき?同じリソース要求が
239 * あったとき???ールの CodeDataを返します?
240 *
241 * 引数にQUERYを渡すことで、DBから、動?コードリソースを作?できます?
242 * 引数の?は、CodeData で定義して? CLM,CODE,LNAME,SNAME の?のままです?
243 * QUERY には、key を引数にとる?があります?つまり?WHERE CLM = ? の様な記述が?です?
244 *
245 * @og.rev 5.4.2.2 (2011/12/14) 新規追??
246 *
247 * @param key コード?キー
248 * @param query 検索SQL(引数に? を?持つ)
249 *
250 * @return CodeData オブジェク?
251 */
252 public CodeData getCodeData( final String key,final String query ) {
253 CodeData codeData = pool.get( key ) ;
254
255 if( codeData == null ) {
256 String[] args = new String[] { key };
257 String[][] vals = DBUtil.dbExecute( query,args,appInfo,DBID );
258
259 int len = vals.length;
260 Map<String,String[]> codeMap = new LinkedHashMap<String,String[]>();
261 for( int i=0; i<len; i++ ) {
262 String[] cdVals = new String[CodeData.MAX_LENGTH]; // 空の配?を毎回作?
263
264 String code = vals[i][CodeData.CODE];
265
266 cdVals[CodeData.CLM] = key ;
267 cdVals[CodeData.CODE] = code;
268 cdVals[CodeData.LNAME] = vals[i][CodeData.LNAME];
269 cdVals[CodeData.SNAME] = vals[i][CodeData.SNAME];
270
271 codeMap.put( code,cdVals );
272 }
273
274 if( ! codeMap.isEmpty() ) {
275 codeData = new CodeData( key,codeMap );
276 pool.put( key,codeData );
277 }
278 }
279 return codeData ;
280 }
281
282 /**
283 * CodeData オブジェクト?キャ?ュを?別にクリアします?
284 * リソース??タの更新など、???更新時に、すべてのキャ?ュ?
285 * 破?る?ではなく?????み破?きる機?です?
286 *
287 * @og.rev 4.0.2.0 (2007/12/25) コードリソースクリア時に対応するラベルリソースもクリアする?
288 *
289 * @param key コード?キー
290 */
291 public void clear( final String key ) {
292
293 // 4.0.2.0 (2007/12/25)
294 CodeData cdata = pool.remove( key );
295 if( cdata != null ) {
296 String clm = cdata.getColumn();
297 for( int i=0; i<cdata.getSize(); i++ ) {
298 LABEL_LOADER.clear( clm + '.' + cdata.getCodeKey( i ) );
299 }
300 }
301 }
302
303 /**
304 * CodeData オブジェクト?キャ?ュをクリアして、?作?します?
305 *
306 */
307 public void clear() {
308 pool.clear();
309 }
310 }