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    }