    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 */
    016package org.opengion.hayabusa.db;
    017
    018import java.util.LinkedHashMap;
    019import java.util.Map;
    020import java.util.Collections;                                                                                   // 6.4.3.1 (2016/02/12)
    021
    022import org.opengion.fukurou.db.DBUtil;
    023import org.opengion.fukurou.db.ApplicationInfo;
    024import org.opengion.hayabusa.common.HybsSystem;
    025import org.opengion.hayabusa.resource.ResourceFactory;
    026import org.opengion.hayabusa.resource.ResourceManager;
    027import static org.opengion.fukurou.system.HybsConst.BUFFER_LARGE;               // 6.1.0.0 (2014/12/26) refactoring
    028
    029/**
    030 * データのコード情報を取り扱うクラスです。
    031 *
    032 * コードのキーとラベルの情報から、HTMLのメニューやリストを作成するための オプション
    033 * タグを作成したり、与えられたキーをもとに、チェック済みのオプションタグを作成したり
    034 * します。
    035 * QUERYのそれぞれのカラムは、以下の意味を持ちます。
    036 *  第１カラム(必須) : ラジオボタンのキー(値)
    037 *  第２カラム       : ラベル(指定されない場合は、ラベルリソースの短縮ラベルを使用します)
    038 *  第３カラム       : クラス そのオプションに色づけなどを行う為の指定します。
    039 *                     NULL(または、ゼロ文字列)の場合は、適用されません。
    040 *  第４カラム       : この値は'false'又は'0'である場合にそのラジオボタンを選択不可にします。
    041 *                     NULL(または、ゼロ文字列)の場合は、選択可能になります。
    042 *
    043 * @og.group 選択データ制御
    044 *
    045 * @version  4.0
    046 * @author   Hiroki Nakamura
    047 * @since    JDK5.0,
    048 */
    049public class Selection_DBRADIO extends Selection_NULL {
    050        private final long              DB_CACHE_TIME                   = (long)HybsSystem.sysInt( "DB_CACHE_TIME" ) ;
    051
    052        private final boolean   isClass ;                       // クエリでクラス属性が指定されているかどうか
    053        private final boolean   isDisable ;                     // クエリで選択不可属性が指定されているかどうか
    054        private final long              createTime ;            // キャッシュの破棄タイミングを計るための作成時間
    055
    056        /** 6.4.3.1 (2016/02/12) Collections.synchronizedMap で同期処理を行います。  */
    057        private final Map<String,Integer>       adrsMap  ;              // 6.4.3.1 (2016/02/12) ついでに変数名も変えておきます。
    058
    059        private final String[]  label   ;               // ラベル
    060        private final String[]  cls     ;               // クラス
    061        private final String[]  disabled ;              // ラジオ単位のdisable
    062
    063        private static final int VAL            = 0;
    064        private static final int LBL            = 1;
    065        private static final int CLS            = 2;
    066        private static final int DISABLED       = 3;
    067
    068        private static final ApplicationInfo APP_INFO;                                                                          // 6.4.1.1 (2016/01/16) appInfo → APP_INFO refactoring
    069        static {
    070                /** コネクションにアプリケーション情報を追記するかどうか指定 */
    071                final boolean USE_DB_APPLICATION_INFO  = HybsSystem.sysBool( "USE_DB_APPLICATION_INFO" ) ;
    072
    073                // 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを設定
    074                if( USE_DB_APPLICATION_INFO ) {
    075                        final String SYSTEM_ID = HybsSystem.sys( "SYSTEM_ID" );
    076                        APP_INFO = new ApplicationInfo();
    077                        // ユーザーID,IPアドレス,ホスト名
    078                        APP_INFO.setClientInfo( SYSTEM_ID,HybsSystem.HOST_ADRS,HybsSystem.HOST_NAME );
    079                        // 画面ID,操作,プログラムID
    080                        APP_INFO.setModuleInfo( "Selection_DBRADIO",null,null );
    081                }
    082                else {
    083                        APP_INFO = null;
    084                }
    085        }
    086
    087        /**
    088         * コンストラクター
    089         *
    090         * ＤＢ検索用のＳＱＬ文を与えて、初期化します。
    091         * SQL文は、KEY,SNAMEで、SNAMEが設定されてない場合は、LNAMEを使用します。
    092         * LNAME は、通常の値を返す場合に、SNAME は、一覧表示の値を返す場合に使用します。
    093         * 特別に、KEY のみの場合は、lang に基づく ResourceManager からﾗﾍﾞﾙを取得します。
    094         * ただし、その場合は、オーナー(SYSTEM_ID)は選べません。
    095         *
    096         * @og.rev 5.1.9.0 (2010/08/01) String[] value 廃止
    097         * @og.rev 6.4.3.1 (2016/02/12) Collections.synchronizedMap に置き換え。
    098         *
    099         * @param       newQuery        DB検索(SQL)文字列
    100         * @param dbid  データベース接続先ID
    101         * @param lang  リソースを使用する場合の言語
    102         */
    103        public Selection_DBRADIO( final String newQuery,final String dbid,final String lang ) {
    104                super();                // 6.4.1.1 (2016/01/16) PMD refactoring. It is a good practice to call super() in a constructor
    105
    106                final String[][] cols = DBUtil.dbExecute( newQuery,null,APP_INFO,dbid );
    107                final int count = cols.length;
    108
    109                label   = new String[count];
    110                cls             = new String[count];
    111                disabled= new String[count];
    112                adrsMap = Collections.synchronizedMap( new LinkedHashMap<>(count) );    // 6.4.3.1 (2016/02/12) ついでに変数名も変えておきます。
    113
    114                final int len   = count > 0 ? cols[0].length : 0 ;
    115                isClass   = len > CLS ;                 // >= 3 と同意;
    116                isDisable = len > DISABLED ;    // >= 4 と同意;
    117
    118                boolean useLabelData = false ;
    119                ResourceManager resource = null;
    120                if( len == 1 ) {
    121                        useLabelData = true;
    122                        resource = ResourceFactory.newInstance( lang );
    123                }
    124
    125                for( int i=0; i<count; i++ ) {
    126                        final String value = cols[i][VAL];
    127                        if( useLabelData ) {
    128                                label[i] = resource.getShortLabel( value );
    129                        }
    130                        else {
    131                                label[i] = cols[i][LBL];
    132                        }
    133
    134                        if( isClass ) {
    135                                cls[i] = cols[i][CLS];
    136                        }
    137                        if( isDisable ) {
    138                                disabled[i] = cols[i][DISABLED];
    139                        }
    140
    141                        adrsMap.put( value, Integer.valueOf( i ) );             // 6.4.3.1 (2016/02/12) ついでに変数名も変えておきます。
    142                }
    143
    144                createTime = System.currentTimeMillis() ;
    145        }
    146
    147        /**
    148         * 初期値が選択済みの 選択肢(オプション)を返します。
    149         * このオプションは、引数の値を初期値とするオプションタグを返します。
    150         *
    151         * @og.rev 6.2.2.4 (2015/04/24) メソッド変更。旧 #getRadio( String , String , boolean )
    152         * @og.rev 6.4.3.1 (2016/02/12) Collections.synchronizedMap に置き換え。
    153         * @og.rev 7.0.1.0 (2018/10/15) XHTML → HTML5 対応(空要素の、"／＞" 止めを、"＞" に変更します)。
    154         *
    155         * @param   name         ラジオの name
    156         * @param   selectValue  選択されている値
    157         * @param   useLabel     ラベル表示の有無 [true:有/false:無]
    158         *
    159         * @return  オプションタグ
    160         * @og.rtnNotNull
    161         */
    162        @Override
    163        public String getOption( final String name,final String selectValue,final boolean useLabel ) {
    164                final String inputTag = "<input type=\"radio\" name=\"" + name + "\" value=\"" ;
    165                final StringBuilder buf = new StringBuilder( BUFFER_LARGE );
    166                for( final Map.Entry<String, Integer> e : adrsMap.entrySet() ) {                // 6.4.3.1 (2016/02/12) ついでに変数名も変えておきます。
    167                        final String val = e.getKey();  // Ver 5.0.0.0 value ⇒ val
    168                        final int valIdx = e.getValue().intValue();
    169                        // 6.0.2.5 (2014/10/31) char を append する。
    170                        if( useLabel ) {
    171                                buf.append( "<label" );
    172                                if( isClass && cls[valIdx] != null && cls[valIdx].length() > 0 ) {
    173                                        buf.append( " class=\"" ).append( cls[valIdx] ).append( '"' );
    174                                }
    175                                buf.append( '>' );
    176                        }
    177                        buf.append( inputTag ).append( val ).append( '"' );
    178                        if( val.equals( selectValue ) ) {
    179                                buf.append( " checked=\"checked\"" );
    180                        }
    181
    182                        if( isDisable && disabled[valIdx] != null && disabled[valIdx].length() > 0 ) {
    183                                if( "false".equalsIgnoreCase( disabled[valIdx] ) || "0".equals( disabled[valIdx] ) ) {
    184                                        buf.append( " disabled=\"disabled\"" );
    185                                }
    186                        }
    187
    188//                      buf.append( "/>" );
    189                        buf.append( '>' );                              // 7.0.1.0 (2018/10/15)
    190                        if( useLabel ) { buf.append( label[valIdx] ).append( "</label>" ); }
    191                }
    192                return buf.toString();
    193        }
    194
    195        /**
    196         * 選択肢(value)に対するラベルを返します。
    197         * 選択肢(value)が、存在しなかった場合は、選択肢そのものを返します。
    198         * このメソッドでは、短縮ラベルを返すかどうかを指定するフラグを指定します。
    199         * getValueLabel( XX,false ) は、getValueLabel( XX ) と同じです。
    200         *
    201         * @og.rev 6.2.3.0 (2015/05/01) マーク表示を廃止。
    202         * @og.rev 6.4.3.1 (2016/02/12) Collections.synchronizedMap に置き換え。
    203         *
    204         * @param       selectValue     選択肢の値
    205         * @param       isSLbl  短縮ラベルを使用する [true:使用する/false:しない]
    206         *
    207         * @return  選択肢のラベル
    208         * @see     #getValueLabel( String )
    209         */
    210        @Override
    211        public String getValueLabel( final String selectValue,final boolean isSLbl ) {
    212                // マッチするアドレスを探す。
    213                final Integer sel = adrsMap.get( selectValue );                 // 6.4.3.1 (2016/02/12) ついでに変数名も変えておきます。
    214
    215                // 6.4.1.1 (2016/01/16) PMD refactoring. A method should have only one exit point, and that should be the last statement in the method
    216                return sel == null ? selectValue : label[sel.intValue()] ;
    217        }
    218
    219        /**
    220         * オブジェクトのキャッシュが時間切れかどうかを返します。
    221         * キャッシュが時間切れ(無効)であれば、true を、有効であれば、
    222         * false を返します。
    223         *
    224         * @return  キャッシュが時間切れなら true
    225         */
    226        @Override
    227        public boolean isTimeOver() {
    228                return ( System.currentTimeMillis() - createTime ) > DB_CACHE_TIME ;
    229        }
    230}