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.db;
017    
018    import org.opengion.hayabusa.common.HybsSystem;
019    import org.opengion.fukurou.util.LogWriter;
020    import org.opengion.hayabusa.resource.ResourceFactory;
021    import org.opengion.hayabusa.resource.ResourceManager;
022    import org.opengion.fukurou.db.DBUtil;
023    import org.opengion.fukurou.util.ApplicationInfo;
024    
025    import java.util.Map;
026    import java.util.HashSet;
027    import java.util.HashMap;
028    
029    /**
030     * ãƒ??タのコード情報を取り扱ã�?‚¯ラスですã?
031     *
032     * コードã?キーとラベルのæƒ??から、HTMLのメニューã‚?ƒªストを作æ?するための オプション
033     * タグを作æ?したりã?与えられたキーをもとに、チェãƒ?‚¯済みのオプションタグを作æ?したã‚?
034     * しますã?
035     * QUERYの第?‘カラãƒ??ã€?�¸択キーになりますã?第?’カラãƒ??ラベルですã?ここまではå¿??ですã?
036     * 第?“カラãƒ?�Œ存在する場合ã?、短縮カラãƒ?�¨して認識されますã?存在しなã�??合ã?ã€?
037     * 短縮ラベルは使用しませんã€?
038     *
039     * メニュー作æ?用に、SELECTæ–?‚’与えますã?
040     * SELECT 値,ラベル[,グループ][,クラス] FROM XXXX でæŒ?®šされã?値、ラベルまではå¿??ã€?
041     * グループã?、optgroup に対してæŒ?®šするラベルですã?クラスは、そのオプションに
042     * 色づけなどを行う為のæŒ?®šですã?
043     * なおã?グループã?クラス は、NULL(またã?、ゼロæ–?­—å?)の場合ã?ã€?�©用されませんã€?
044     *
045     * @og.group 選択データ制御
046     *
047     * @version  4.0
048     * @author   Kazuhiko Hasegawa
049     * @since    JDK5.0,
050     */
051    // public class Selection_DB implements Selection {
052    public class Selection_DB extends Selection_NULL {
053            // 3.5.4.8 (2004/02/23) USE_MULTI_KEY_SELECT を定義しておきますã?
054            private final boolean USE_MULTI_KEY_SELECT      = HybsSystem.sysBool( "USE_MULTI_KEY_SELECT" ) ;
055            private final long        DB_CACHE_TIME                 = (long)HybsSystem.sysInt( "DB_CACHE_TIME" ) ;
056    
057            private final boolean   isMultiSelect ;
058            private final boolean   isShortLavel ;          // 短縮ラベルを使用できるかどã�?�‹
059            private final long              createTime ;            // キャãƒ?‚·ュの破æ£?‚¿イミングを計るための作æ?時間
060    
061            private final int[]             ADRS  ;
062            private final String    CACHE ;
063            private final int               LEN      ;
064            private final int[]             LADRS  ; // 5.1.3.0 (2010/02/01)
065            private final String    LCACHE ; // 5.1.3.0 (2010/02/01)
066            private final int               LLEN   ; // 5.1.3.0 (2010/02/01)
067            private final Map<String,Integer> map  ;
068    
069            private final String[]  value ;         // 値
070            private final String[]  label ;         // ラベル
071            private final String[]  slabel ;        // 短縮ラベル
072    
073            private static final int VAL  = 0;
074            private static final int LBL  = 1;
075            private static final int SLBL = 2;
076            private static final int GRP  = 3;
077            private static final int CLS  = 4;
078    
079            // 3.8.7.0 (2006/12/15) アクセスログ取得ã?為,ApplicationInfoオブジェクトを設å®?
080            private static final ApplicationInfo appInfo;
081            static {
082                    /** コネクションにアプリケーションæƒ??を追記するかどã�?�‹æŒ?®?*/
083                    boolean USE_DB_APPLICATION_INFO  = HybsSystem.sysBool( "USE_DB_APPLICATION_INFO" ) ;
084    
085                    // 3.8.7.0 (2006/12/15) アクセスログ取得ã?為,ApplicationInfoオブジェクトを設å®?
086                    if( USE_DB_APPLICATION_INFO ) {
087                            String SYSTEM_ID = HybsSystem.sys( "SYSTEM_ID" );
088                            appInfo = new ApplicationInfo();
089                            // ユーザーID,IPアドレス,ホスト名
090                            appInfo.setClientInfo( SYSTEM_ID,HybsSystem.HOST_ADRS,HybsSystem.HOST_NAME );
091                            // 画面ID,操ä½?プログラãƒ?D
092                            appInfo.setModuleInfo( "Selection_DB",null,null );
093                    }
094                    else {
095                            appInfo = null;
096                    }
097            }
098    
099            /**
100             * コンストラクター
101             *
102             * ?¤?¢検索用の?³?±?¬æ–?‚’与えて、å?期化しますã?
103             * SQLæ–??、KEY,LNAME [,SNAME] で、第?“é?がなければ、LNAME を使用しますã?
104             * LNAME はã€??常の値を返す場合に、SNAME は、ä¸?¦§表示の値を返す場合に使用しますã?
105             * 特別に、KEY のみの場合ã?、lang に基づã�?ResourceManager から?—ベルを取得しますã?
106             * ただしã?そã?場合ã?、オーナã?(SYSTEM_ID)は選べませんã€?
107             *
108             * @og.rev 3.5.4.2 (2003/12/15) コンストラクター 新規追åŠ?
109             * @og.rev 3.6.0.9 (2004/12/03) isMultiSelect の判定をラベル部のユニã?ク度で判定しますã?
110             * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得ã?為,ApplicationInfoオブジェクトを設å®?
111             * @og.rev 3.8.9.2 (2007/07/28) グループと、クラスを追åŠ??Selectæ–??第?“ã?第?”引数としてæŒ?®šã?
112             * @og.rev 4.0.0.0 (2006/11/15) lang 属æ?を追åŠ?�—ますã?
113             * @og.rev 4.3.8.0 (2009/08/01) ãƒ??ルチップ表示機è?追åŠ?
114             * @og.rev 5.1.3.0 (2010/02/01) ラベル(短)がnullの場合でもã?ラベル(短)で表示されてしまã�?ƒ�グを修正
115             * @og.rev 5.1.3.0 (2010/02/01) ä¸?¦§表示以外ã?、ツールチップ表示しなã�?
116             *
117             * @param newQuery      DB検索(SQL)æ–?­—å?
118             * @param dbid          ãƒ??タベã?ス接続å?ID
119             * @param lang          リソースを使用する場合ã?è¨?ª?
120             */
121            public Selection_DB( final String newQuery,final String dbid,final String lang ) {
122    
123                    String[][] cols = DBUtil.dbExecute( newQuery,null,appInfo,dbid );       // 3.8.7.0 (2006/12/15)
124                    int count = cols.length;
125    
126                    value   = new String[count];
127                    label   = new String[count];
128                    slabel  = new String[count];
129                    ADRS    = new int[count];
130                    map             = new HashMap<String,Integer>(count);
131    
132                    int len = ( count > 0 ) ? cols[0].length : 0 ;
133                    isShortLavel  = len > SLBL ; // >= 3 と同意;
134                    boolean isGrp = len > GRP ;          // >= 4 と同意;
135                    boolean isCls = len > CLS ;          // >= 5 と同意;
136    
137                    boolean useLabelData = false ;
138                    ResourceManager resource = null;
139                    if( len == 1 ) {
140                            useLabelData = true;
141                            resource = ResourceFactory.newInstance( lang );
142                    }
143    
144                    // 3.6.0.9 (2004/12/03)
145                    HashSet<String> set = new HashSet<String>();
146                    boolean flag = USE_MULTI_KEY_SELECT;    // 判定å?ç�?‚’行う。false なら判定å?ç�?‚‚行わなã�??
147    
148                    StringBuilder buf = new StringBuilder( HybsSystem.BUFFER_LARGE );
149                    String bkGroupKey = "";
150                    for( int i=0; i<count; i++ ) {
151                            value[i] = cols[i][VAL];
152                            if( useLabelData ) {
153                                    label[i] = resource.getLabel( value[i] );
154                            }
155                            else {
156                                    label[i] = cols[i][LBL];
157                                    if( isShortLavel ) { slabel[i] = cols[i][SLBL]; }
158                            }
159                            map.put( value[i], Integer.valueOf( i ) );
160    
161                            // 3.8.9.2 (2007/07/28)
162                            if( isGrp ) {
163                                    String groupKey = cols[i][GRP];
164                                    if( !groupKey.equals( bkGroupKey ) ) {  // キーブレイク
165                                            if( ! "".equals( bkGroupKey ) ) {
166                                                    buf.append( "</optgroup>" );
167                                            }
168                                            if( ! "".equals( groupKey ) ) {
169                                                    buf.append( "<optgroup label=\"" + groupKey + "\">" );
170                                            }
171                                            bkGroupKey = groupKey;
172                                    }
173                            }
174    
175                            buf.append( "<option value=\"" ).append( value[i] ).append( "\"" );
176                            ADRS[i] = buf.length() ;
177                            if( isCls ) {
178                                    String classKey = cols[i][CLS];
179                                    if( ! "".equals( classKey ) ) {
180                                            buf.append( " class=\"" ).append( classKey ).append( "\"" );
181                                    }
182                            }
183                            // 4.3.8.0 (2009/08/01) slabel利用の場合ã?labelをtitle属æ?にセãƒ?ƒˆ
184                            //buf.append( ">" ).append( label[i] ).append( "</option>" );
185                            if( isShortLavel && slabel[i] != null && slabel[i].length() > 0 ){ // 5.1.3.0 (2010/02/01)
186                                    if( !label[i].equals( slabel[i] ) ){ // slabelとlabelが異なるå?合ã?み
187                                            buf.append( " title=\"" ).append( label[i] ).append( "\"" );
188                                    }
189                                    buf.append( ">" ).append( slabel[i] );
190                            }
191                            else{
192                                    buf.append( ">" ).append( label[i] );
193                            }
194                            buf.append( "</option>" );
195    
196                            // 3.6.0.9 (2004/12/03)
197                            if( flag && label[i].length() > 0 ) {
198                                    flag = set.add( label[i].substring(0,1) );      // 重è¤?™‚は false
199                            }
200                    }
201                    if( isGrp && ! "".equals( bkGroupKey ) ) {
202                            buf.append( "</optgroup>" );
203                    }
204    
205                    CACHE = buf.toString();
206                    LEN   = CACHE.length() + 30;
207    
208                    // 5.1.3.0 (2010/02/01) ãƒ??ルチップ表示が適用されてã�?‚‹場合ã?み、ツールチップなしã?状態ã?optionをキャãƒ?‚·ュするã€?
209                    if( CACHE.indexOf( "title=\"" ) < 0 ) {
210                            LADRS  = null;
211                            LCACHE = null;
212                            LLEN   = 0;
213                    }
214                    else {
215                            LADRS  = new int[count];
216                            StringBuilder lbuf = new StringBuilder( HybsSystem.BUFFER_LARGE );
217    
218                            bkGroupKey = "";
219                            for( int i=0; i<count; i++ ) {
220                                    if( isGrp ) {
221                                            String groupKey = cols[i][GRP];
222                                            if( !groupKey.equals( bkGroupKey ) ) {
223                                                    if( ! "".equals( bkGroupKey ) ) { lbuf.append( "</optgroup>" ); }
224                                                    if( ! "".equals( groupKey ) )   { lbuf.append( "<optgroup label=\"" + groupKey + "\">" ); }
225                                                    bkGroupKey = groupKey;
226                                            }
227                                    }
228                                    lbuf.append( "<option value=\"" ).append( value[i] ).append( "\"" );
229                                    LADRS[i] = lbuf.length() ;
230                                    if( isCls && ! "".equals( cols[i][CLS] ) ) {
231                                            lbuf.append( " class=\"" ).append( cols[i][CLS] ).append( "\"" );
232                                    }
233                                    lbuf.append( ">" ).append( label[i] ).append( "</option>" );
234                            }
235                            if( isGrp && ! "".equals( bkGroupKey ) ) {
236                                    lbuf.append( "</optgroup>" );
237                            }
238                            LCACHE = lbuf.toString();
239                            LLEN   = LCACHE.length() + 30;
240                    }
241    
242                    isMultiSelect = USE_MULTI_KEY_SELECT && ! flag ;        // flag の反転に注æ„?
243                    createTime = System.currentTimeMillis() ;
244            }
245    
246            /**
247             * 初期値が選択済みの 選択肢(オプション)を返しますã?
248             * こã?オプションは、引数の値をå?期å?とするオプションタグを返しますã?
249             * こã?メソãƒ?ƒ‰では、ラベル(短)が設定されてã�?‚‹場合でもã?これを使用せずにå¿?�šラベル(長)を使用しますã?
250             *
251             * @og.rev 3.6.0.6 (2004/10/22) シーケンスアクセス機è?を指定すã‚?seqFlag を導å?
252             * @og.rev 4.0.0.0 (2005/01/31) selectValue がã?null/ゼロæ–?­—å?でなã�??合にã€?�¸択肢になã�??合ã?、エラー
253             * @og.rev 5.7.7.1 (2014/06/13) Selection_NULL ã‚?継承するため、削除
254             *
255             * @param   selectValue  選択されてã�?‚‹値
256             * @param   seqFlag  シーケンスアクセス機è? [true:ON/false:OFF]
257             *
258             * @return  オプションタグ
259             * @see     #getOption( String, boolean, boolean )
260             */
261    //      public String getOption( final String selectValue,final boolean seqFlag ) {
262    //              return getOption( selectValue, seqFlag, false );
263    //      }
264    
265            /**
266             * 初期値が選択済みの 選択肢(オプション)を返しますã?
267             * こã?オプションは、引数の値をå?期å?とするオプションタグを返しますã?
268             * こã?メソãƒ?ƒ‰では、引数のuseShortLabelがtrueにæŒ?®šされた場合に、ラベル(短)をã?ースとした
269             * ãƒ??ルチップ表示を行いますã?
270             *
271             * @og.rev 5.1.3.0 (2010/02/01) 追åŠ?
272             *
273             * @param   selectValue  選択されてã�?‚‹値
274             * @param   seqFlag  シーケンスアクセス機è? [true:ON/false:OFF]
275             * @param   useShortLabel ラベル(短)をã?ースとしたオプション表示を行うかどã�?�‹ã€?
276             *
277             * @return  オプションタグ
278             * @see     #getOption( String, boolean )
279             */
280            @Override
281            public String getOption( final String selectValue,final boolean seqFlag, final boolean useShortLabel ) {
282                    int[] adrs = null;
283                    String cache = null;
284                    int len = 0;
285                    if( !useShortLabel && LCACHE != null && LCACHE.length() > 0 ) {
286                            adrs = LADRS;
287                            cache = LCACHE;
288                            len = LLEN;
289                    }
290                    else {
291                            adrs = ADRS;
292                            cache = CACHE;
293                            len = LEN;
294                    }
295    
296                    // マッチするアドレスを探すã?
297                    Integer sel = map.get( selectValue );
298    
299                    if( sel == null ) {
300                            // 4.0.0 (2005/01/31)
301                            if( selectValue != null && selectValue.length() > 0 ) {
302                                    String errMsg = "DBコードに存在しなã�??が指定されましたã€?
303                                                            + " value=[" + selectValue + "]"
304                                                            + HybsSystem.CR ;
305                                    LogWriter.log( errMsg );
306                            }
307                            return cache;
308                    }
309                    else {
310                            int selected = sel.intValue();
311                            StringBuilder buf = new StringBuilder( len );
312                            // 3.6.0.6 (2004/10/22) シーケンスアクセス機è?を指定すã‚?seqFlag を導å?
313                            if( seqFlag ) {
314                                    buf.append( "<option value=\"" ).append( value[selected] ).append( "\"" );
315                            }
316                            else {
317                                    buf.append( cache.substring( 0,adrs[selected] ) );
318                            }
319                            buf.append( " selected=\"selected\"" );
320                            buf.append( cache.substring( adrs[selected] ) );
321                            return buf.toString() ;
322                    }
323            }
324    
325            /**
326             * 初期値が選択済みの 選択肢(オプション)を返しますã?
327             * こã?オプションは、引数の値をå?期å?とするオプションタグを返しますã?
328             * ※ こã?クラスでは実è£?�•れてã�?�¾せんã€?
329             *
330             * @og.rev 2.1.0.1 (2002/10/17) 選択リストを、正方向にしか選べなã�?‚ˆã�?�«する sequenceFlag を導å?する
331             * @og.rev 3.8.6.0 (2006/09/29) useLabel 属æ? 追åŠ?
332             * @og.rev 5.7.7.1 (2014/06/13) Selection_NULL ã‚?継承するため、削除
333             *
334             * @param   name         ラジオの name
335             * @param   selectValue  選択されてã�?‚‹値
336             * @param   useLabel     ラベル表示の有無 [true:æœ?false:無]
337             *
338             * @return  オプションタグ
339             */
340    //      public String getRadio( final String name,final String selectValue,final boolean useLabel ) {
341    //              String errMsg = "こã?クラスでは実è£?�•れてã�?�¾せんã€?;
342    //              throw new UnsupportedOperationException( errMsg );
343    //      }
344    
345            /**
346             * 初期値が選択済みの 選択肢(オプション)を返しますã?
347             * こã?オプションは、引数の値をå?期å?とするオプションタグを返しますã?
348             * ※ こã?クラスでは実è£?�•れてã�?�¾せんã€?
349             *
350             * @og.rev 5.7.7.1 (2014/06/13) Selection_NULL ã‚?継承するため、削除
351             *
352             * @param   selectValue  選択されてã�?‚‹値
353             *
354             * @return  オプションタグ
355             */
356    //      public String getRadioLabel( final String selectValue ) {
357    //              String errMsg = "こã?クラスでは実è£?�•れてã�?�¾せんã€?;
358    //              throw new UnsupportedOperationException( errMsg );
359    //      }
360    
361            /**
362             * 選択肢(value)に対するラベルを返しますã?
363             * 選択肢(value)がã?存在しなかったå?合ã?ã€?�¸択肢そã?もã?を返しますã?
364             * getValueLabel( XX ) は、getValueLabel( XX,false ) と同じですã?
365             *
366             * @og.rev 5.7.7.1 (2014/06/13) Selection_NULL ã‚?継承するため、削除
367             *
368             * @param   selectValue 選択肢の値
369             *
370             * @return  選択肢のラベル
371             * @see     #getValueLabel( String,boolean )
372             */
373    //      public String getValueLabel( final String selectValue ) {
374    //              return getValueLabel( selectValue,false );
375    //      }
376    
377            /**
378             * 選択肢(value)に対するラベルを返しますã?
379             * 選択肢(value)がã?存在しなかったå?合ã?ã€?�¸択肢そã?もã?を返しますã?
380             * こã?メソãƒ?ƒ‰では、短縮ラベルを返すかどã�?�‹を指定するフラグを指定しますã?
381             * getValueLabel( XX,false ) は、getValueLabel( XX ) と同じですã?
382             *
383             * @og.rev 4.0.0.0 (2005/11/30) を追åŠ?
384             * @og.rev 5.3.5.0 (2011/05/01) 名称(短)表示時に名称(長)をツールチップで表示するã€?
385             *
386             * @param       selectValue     選択肢の値
387             * @param       flag    短縮ラベルを使用する [true:使用する/false:しない]
388             *
389             * @return  選択肢のラベル
390             * @see     #getValueLabel( String )
391             */
392            @Override
393            public String getValueLabel( final String selectValue,final boolean flag ) {
394                    // マッチするアドレスを探すã?
395                    Integer sel = map.get( selectValue );
396    
397                    if( sel == null ) {
398                            return selectValue;
399                    }
400                    else {
401                            if( isShortLavel && flag ) {
402                                    return "<span title=\""+label[sel.intValue()]+"\">"+slabel[sel.intValue()]+"</span>";
403                            }
404                            else {
405                                    return label[sel.intValue()] ;
406                            }
407                    }
408            }
409    
410            /**
411             * マルチã?キーセレクトを使用するかどã�?�‹を返しますã?
412             * true?š使用する。false:使用しなã�?ですã?
413             * ただしã?実際に使用するかどã�?�‹は、HTML出力時に決めることがå?来ますã?
414             * ここでは、USE_MULTI_KEY_SELECT ã�?true で、USE_SIZE(=20)以上ã?場合に
415             * true を返しますã?
416             *
417             * @og.rev 3.5.5.7 (2004/05/10) 新規作æ?
418             *
419             * @return  選択リストで、ã?ルチã?キーセレクトを使用するかどã�?�‹(true:使用する)
420             */
421            @Override
422            public boolean useMultiSelect() {
423                    return isMultiSelect;
424            }
425    
426            /**
427             * オブジェクトã?キャãƒ?‚·ュが時間å?れかどã�?�‹を返しますã?
428             * キャãƒ?‚·ュが時間å?ã‚?無効)であれば、true をã?有効であればã€?
429             * false を返しますã?
430             *
431             * @og.rev 4.0.0.0 (2005/01/31) 新規作æ?
432             *
433             * @return  キャãƒ?‚·ュが時間å?れなã‚?true
434             */
435            @Override
436            public boolean isTimeOver() {
437                    return ( System.currentTimeMillis() - createTime ) > DB_CACHE_TIME ;
438            }
439    }