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    }