    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 org.opengion.fukurou.system.LogWriter;
    019import org.opengion.hayabusa.resource.CodeData;
    020import org.opengion.fukurou.util.StringUtil ;                                           // 6.2.2.0 (2015/03/27)
    021
    022import static org.opengion.fukurou.system.HybsConst.CR ;                                // 6.1.0.0 (2014/12/26)
    023import static org.opengion.fukurou.system.HybsConst.BUFFER_MIDDLE;      // 6.1.0.0 (2014/12/26) refactoring
    024
    025/**
    026 * データのコード情報を取り扱うクラスです。
    027 *
    028 * コードのキーとラベルの情報から、HTMLのメニューやリストを作成するための オプション
    029 * タグを作成したり、与えられたキーをもとに、チェック済みのオプションタグを作成したり
    030 * します。
    031 *
    032 * @og.rev 5.7.7.1 (2014/06/13) Selection_NULL を 基本実装とします。
    033 * @og.group 選択データ制御
    034 *
    035 * @version  4.0
    036 * @author   Kazuhiko Hasegawa
    037 * @since    JDK5.0,
    038 */
    039public class Selection_CODE extends Selection_NULL {
    040        private final CodeData codeData ;
    041
    042        private final int[]    ADRS  ;
    043        private final String   CACHE ;
    044        private final int      LEN   ;
    045
    046        private final int[]    LADRS  ;         // 5.1.3.0 (2010/02/01)
    047        private final String   LCACHE ;         // 5.1.3.0 (2010/02/01)
    048        private final int      LLEN   ;         // 5.1.3.0 (2010/02/01)
    049
    050        private final String addKeyLabel ;      // 6.2.0.0 (2015/02/27) キー:ラベル形式
    051
    052        /**
    053         * コンストラクター
    054         *
    055         * @og.rev 4.0.0.0 (2007/11/07) コードリソースの有無はDBColumnでチェックする。
    056         * @og.rev 4.3.8.0 (2009/08/01) ツールチップ表示機能追加
    057         * @og.rev 5.1.3.0 (2010/02/01) 一覧表示以外は、ツールチップ表示しない
    058         * @og.rev 5.1.9.0 (2010/08/01) グループ機能とパラメータ機能の追加
    059         * @og.rev 5.6.8.2 (2013/09/20) ツールチップは未加工のlongLabelを利用に修正
    060         * @og.rev 5.7.7.1 (2014/06/13) Selection_NULL を 継承するため、super( null ); を追加します。
    061         * @og.rev 6.2.0.0 (2015/02/27) コードリソースのパラメータの指定方法を変更します。
    062         * @og.rev 6.2.0.0 (2015/02/27) キー:ラベル形式で表示するかどうかを、指定できるようにします。
    063         * @og.rev 6.2.2.0 (2015/03/27) BRと\nを相互に変換する処理を追加
    064         * @og.rev 6.2.2.3 (2015/04/10) htmlフィルターに、BR→改行処理機能を追加。
    065         * @og.rev 6.7.7.1 (2017/04/07) コードリソースに概要を記入すると、isUse が無効になっていたのを修正。
    066         *
    067         * @param       cdData  コードデータオブジェクト
    068         * @param       addKeyLabel キー:ラベル形式で表示するかどうか[true/false/null]
    069         */
    070        public Selection_CODE( final CodeData cdData,final String addKeyLabel ) {
    071                super();                // 6.4.1.1 (2016/01/16) PMD refactoring. It is a good practice to call super() in a constructor
    072                codeData = cdData ;
    073                this.addKeyLabel = addKeyLabel;                 // 6.2.0.0 (2015/02/27) キー:ラベル形式
    074                final int size = codeData.getSize();
    075
    076                // 5.1.9.0 (2010/08/01) グループ機能とパラメータの判定
    077                final boolean isLbl = codeData.useLevel();
    078                final boolean isCls = codeData.useParam();
    079                boolean isLblSet = false;                               // optgroup の設定に使う。
    080
    081                ADRS  = new int[size];
    082                final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE );
    083                boolean useTitle = false;                                                               // 4.3.8.0 (2009/08/01) title属性付加フラグ
    084                for( int i=0; i<size; i++ ) {
    085                        if( ! codeData.isUse(i) ) { continue; }
    086
    087                        // 6.2.0.0 (2015/02/27) キー:ラベル形式
    088                        final String cdkey = codeData.getCodeKey(i);
    089                        final String kv = "true".equalsIgnoreCase( addKeyLabel ) ? cdkey + ':' : "" ;
    090                        final String rslbl = codeData.getRawShortLabel(i);
    091
    092                        // 5.1.9.0 (2010/08/01) コードレベルの判定
    093                        if( isLbl && "0".equals( codeData.getCodeLevel(i) ) ) {
    094                                if( isLblSet ) { buf.append( "</optgroup>" ); }
    095
    096                                buf.append( "<optgroup label=\"" + rslbl + "\">" );
    097                                isLblSet = true;
    098                                continue;
    099                        }
    100
    101                        // 6.0.2.5 (2014/10/31) char を append する。
    102                        // 6.2.0.0 (2015/02/27) キー:ラベル形式
    103                        buf.append( "<option value=\"" ).append( cdkey ).append( '"' );
    104                        ADRS[i] = buf.length() ;
    105
    106                        // 5.1.9.0 (2010/08/01) パラメータの利用
    107                        if( isCls ) {
    108                                // 6.2.0.0 (2015/02/27) コードリソースのパラメータの指定方法を変更します。
    109                                final String paramKey = codeData.getCodeParam(i);
    110                                setCodeParam( buf,paramKey );
    111                        }
    112
    113                        // 6.2.0.0 (2015/02/27) Description があれば、優先して title 属性に設定します。
    114                        final String desc = codeData.getDescription(i);
    115                        if( desc.isEmpty() ) {
    116                                // 4.3.8.0 (2009/08/01) LongLabelはRawShortLabelと異なるときにツールチップとして表示させる
    117                                final String lblb  = codeData.getRawLongLabel(i); // 5.6.8.2 (2013/09/20) ここでは生の名称長を取る
    118                                if( ! rslbl.equals( lblb ) ){
    119                                        // 6.2.2.0 (2015/03/27) BRと\nを相互に変換する処理を追加
    120                                        buf.append(" title=\"").append( StringUtil.htmlFilter( lblb,true ) ).append( '"' );
    121                                        useTitle = true;
    122                                }
    123                        }
    124                        else {
    125                                // 6.2.2.0 (2015/03/27) BRと\nを相互に変換する処理を追加
    126                                buf.append(" title=\"").append( StringUtil.htmlFilter( desc,true ) ).append( '"' );
    127                                useTitle = true;
    128                        }
    129
    130                        // ShortLabelをBODYにする。
    131                        // 6.2.0.0 (2015/02/27) キー:ラベル形式
    132                        buf.append( '>' ).append( kv ).append( rslbl ).append( "</option>" );
    133                }
    134                if( isLbl ) {
    135                        buf.append( "</optgroup>" );
    136                }
    137
    138                CACHE = buf.toString();
    139                LEN   = CACHE.length() + 30;
    140
    141                // 5.1.3.0 (2010/02/01) ツールチップ表示が適用されている場合のみ、ツールチップなしの状態のoptionをキャッシュする。
    142                if( useTitle ) {
    143                        isLblSet = false;
    144
    145                        LADRS  = new int[size];
    146                        final StringBuilder lbuf = new StringBuilder( BUFFER_MIDDLE );
    147                        for( int i=0; i<size; i++ ) {
    148                                if( ! codeData.isUse(i) ) { continue; }         // 6.7.7.1 (2017/04/07)
    149
    150                                // 6.2.0.0 (2015/02/27) キー:ラベル形式
    151                                final String cdkey = codeData.getCodeKey(i);
    152                                final String kv = "true".equalsIgnoreCase( addKeyLabel ) ? cdkey + ':' : "" ;
    153                                final String lblb  = codeData.getLongLabel(i);
    154                                // 5.1.9.0 (2010/08/01) グループ機能の判定
    155                                if( isLbl && "0".equals( codeData.getCodeLevel(i) ) ) {
    156                                        if( isLblSet ) { lbuf.append( "</optgroup>" ); }
    157
    158                                        lbuf.append( "<optgroup label=\"" + lblb + "\">" );
    159                                        isLblSet = true;
    160                                        continue;
    161                                }
    162
    163                                // 6.0.2.5 (2014/10/31) char を append する。
    164                                // 6.2.0.0 (2015/02/27) キー:ラベル形式
    165                                lbuf.append( "<option value=\"" ).append( cdkey ).append( '"' );
    166                                LADRS[i] = lbuf.length() ;
    167
    168                                // 5.1.9.0 (2010/08/01) パラメータの利用
    169                                if( isCls ) {
    170                                        // 6.2.0.0 (2015/02/27) コードリソースのパラメータの指定方法を変更します。
    171                                        final String paramKey = codeData.getCodeParam(i);
    172                                        setCodeParam( lbuf,paramKey );
    173                                }
    174
    175                                // 6.2.0.0 (2015/02/27) キー:ラベル形式
    176                                lbuf.append( '>' ).append( kv ).append( lblb ).append( "</option>" );
    177                        }
    178                        if( isLbl ) {
    179                                buf.append( "</optgroup>" );
    180                        }
    181
    182                        LCACHE = lbuf.toString();
    183                        LLEN   = LCACHE.length() + 30;
    184                }
    185                else {
    186                        LADRS  = ADRS;
    187                        LCACHE = CACHE;
    188                        LLEN   = LEN;
    189                }
    190        }
    191
    192        /**
    193         * 初期値が選択済みの 選択肢(オプション)を返します。
    194         * このオプションは、引数の値を初期値とするオプションタグを返します。
    195         * このメソッドでは、引数のuseShortLabelがtrueに指定された場合に、ラベル(短)をベースとした
    196         * ツールチップ表示を行います。
    197         *
    198         * @og.rev 5.1.3.0 (2010/02/01) 追加
    199         *
    200         * @param   selectValue  選択されている値
    201         * @param   seqFlag  シーケンスアクセス機能 [true:ON/false:OFF]
    202         * @param   useShortLabel ラベル(短)をベースとしたオプション表示を行うかどうか。
    203         *
    204         * @return  オプションタグ
    205         * @og.rtnNotNull
    206         */
    207        @Override
    208        public String getOption( final String selectValue,final boolean seqFlag, final boolean useShortLabel ) {
    209                int[] adrs = null;
    210                String cache = null;
    211                int len = 0;
    212                if( useShortLabel ) {
    213                        adrs  = ADRS;
    214                        cache = CACHE;
    215                        len   = LEN;
    216                }
    217                else {
    218                        adrs  = LADRS;
    219                        cache = LCACHE;
    220                        len   = LLEN;
    221                }
    222
    223                // マッチするアドレスを探す。
    224                final int selected = codeData.getAddress( selectValue );
    225
    226                if( selected < 0 ) {
    227                        // 4.0.0 (2005/01/31)
    228                        if( selectValue != null && selectValue.length() > 0 ) {
    229                                final String errMsg = "コードに存在しない値が指定されました。"
    230                                                        + " value=[" + selectValue + "]"
    231                                                        + CR + codeData ;
    232                                LogWriter.log( errMsg );
    233                        }
    234                        return cache;
    235                }
    236                else {
    237                        final StringBuilder buf = new StringBuilder( len + 100 );                                               // 6.1.0.0 (2014/12/26) refactoring
    238                        // 3.6.0.6 (2004/10/22) シーケンスアクセス機能を指定する seqFlag を導入
    239                        if( seqFlag ) {
    240                                buf.append( "<option value=\"" ).append( codeData.getCodeKey(selected) ).append( '"' );         // 6.0.2.5 (2014/10/31) char を append する。
    241                        }
    242                        else {
    243                                buf.append( cache.substring( 0,adrs[selected] ) );
    244                        }
    245                        buf.append( " selected=\"selected\"" )
    246                                .append( cache.substring( adrs[selected] ) );
    247                        return buf.toString() ;
    248                }
    249        }
    250
    251        /**
    252         * 選択肢(value)に対するラベルを返します。
    253         * 選択肢(value)が、存在しなかった場合は、選択肢そのものを返します。
    254         * このメソッドでは、短縮ラベルを返すかどうかを指定するフラグを指定します。
    255         * getValueLabel( XX,false ) は、getValueLabel( XX ) と同じです。
    256         *
    257         * @og.rev 4.0.0.0 (2005/11/30) を追加
    258         * @og.rev 6.2.0.0 (2015/02/27) キー:ラベル形式で表示するかどうかを、指定できるようにします。
    259         *
    260         * @param       selectValue     選択肢の値
    261         * @param       isSLbl  短縮ラベル使用可否 [true:使用する/false:しない]
    262         *
    263         * @return  選択肢のラベル
    264         * @see     #getValueLabel( String )
    265         */
    266        @Override
    267        public String getValueLabel( final String selectValue,final boolean isSLbl ) {
    268                // マッチするアドレスを探す。
    269                final int selected = codeData.getAddress( selectValue );
    270
    271                if( selected < 0 ) {
    272                        // マッチしなければ、選択肢そのものを返す。
    273                        return selectValue;
    274                }
    275                else {
    276                        // 6.2.0.0 (2015/02/27) キー:ラベル形式
    277                        final String lbl = isSLbl ? codeData.getShortLabel(selected) : codeData.getLongLabel(selected);
    278
    279                        return "true".equalsIgnoreCase( addKeyLabel ) ? selectValue + ':' + lbl : lbl ;
    280                }
    281        }
    282
    283}