    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.util.Cleanable;
    019import org.opengion.hayabusa.common.HybsSystemException ;
    020import org.opengion.hayabusa.common.SystemManager ;
    021import org.opengion.hayabusa.resource.CodeData;
    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
    025import java.util.Map;
    026import java.util.WeakHashMap ;
    027import java.util.Collections ;                                                                                  // 6.4.3.1 (2016/02/12) ConcurrentHashMap が使えないため。
    028
    029/**
    030 * Selectionオブジェクトを取得する為に使用するファクトリクラスです。
    031 *
    032 * Selectionオブジェクト のキー(codeName)を元に、オブジェクトをキャッシュ管理
    033 * することが、主な機能です。
    034 *
    035 * @og.rev 3.5.5.7 (2004/05/10) 新規作成
    036 * @og.group 選択データ制御
    037 *
    038 * @version  4.0
    039 * @author   Kazuhiko Hasegawa
    040 * @since    JDK5.0,
    041 */
    042public final class SelectionFactory {
    043        // private static final Map<String,Selection>  codeMap = new WeakHashMap<>();
    044        /** 6.4.3.1 (2016/02/12) PMD refactoring. Collections.synchronizedMap で対応。  */
    045        private static final Map<String,Selection>      DB_MAP                  = Collections.synchronizedMap( new WeakHashMap<>( BUFFER_MIDDLE ) );    // 6.4.3.1 (2016/02/12) Collections.synchronizedMap
    046        /** 6.4.3.1 (2016/02/12) PMD refactoring. Collections.synchronizedMap で対応。  */
    047        private static final Map<String,Selection>      DB_RADIO_MAP    = Collections.synchronizedMap( new WeakHashMap<>( BUFFER_MIDDLE ) );    // 6.4.3.1 (2016/02/12) Collections.synchronizedMap
    048
    049        // 4.0.0 (2005/01/31) Cleanable インターフェースによる初期化処理
    050        static {
    051                final Cleanable clr = new Cleanable() {
    052                        /**
    053                         * 初期化(クリア)します。
    054                         * 主に、キャッシュクリアで利用します。
    055                         */
    056                        public void clear() {
    057                                SelectionFactory.clear();
    058                        }
    059                };
    060
    061                SystemManager.addCleanable( clr );
    062        }
    063
    064        /**
    065         *  デフォルトコンストラクターをprivateにして、
    066         *  オブジェクトの生成をさせないようにする。
    067         *
    068         */
    069        private SelectionFactory() {}
    070
    071        /**
    072         * DB検索(SQL)文字列より、データベースSelectionオブジェクトを構築します。
    073         * Selection_DB では、検索行毎のクエリーがあるため、name + query でキャッシュします。
    074         *
    075         * @og.rev 4.0.0.0 (2006/11/15) lang 属性を追加します。
    076         * @og.rev 6.2.0.0 (2015/02/27) キー:ラベル形式で表示するかどうかを、指定できるようにします。
    077         * @og.rev 6.4.3.1 (2016/02/12) PMD refactoring. Collections.synchronizedMap で対応。
    078         *
    079         * @param   query DB検索(SQL)文字列
    080         * @param       dbid  データベース接続先ID
    081         * @param       lang  リソースを使用する場合の言語
    082         * @param       addKeyLabel キー:ラベル形式で表示するかどうか[true/false/null]
    083         *
    084         * @return  Selectionオブジェクト
    085         */
    086        public static Selection newDBSelection( final String query,final String dbid,final String lang,final String addKeyLabel ) {
    087                final String key = query+dbid+lang+addKeyLabel;                                         // 6.2.0.0 (2015/02/27) キー:ラベル形式
    088
    089                // 6.4.3.1 (2016/02/12) v は、Selection オブジェクト
    090                // Selection select = DB_MAP.get( key );
    091                // Map#compute ： 戻り値は、新しい値。追加有り、置換有り、削除有り
    092                return DB_MAP.compute( key ,(k,v) ->
    093                                                v == null || v.isTimeOver() ? new Selection_DB( query,dbid,lang,addKeyLabel ) : v );
    094        }
    095
    096        /**
    097         * DB検索(SQL)文字列より、データベースSelectionオブジェクトを構築します。
    098         * Selection_DB では、検索行毎のクエリーがあるため、name + query でキャッシュします。
    099         *
    100         * @og.rev 4.3.3.6 (2008/11/15) 新規作成
    101         * @og.rev 6.4.3.1 (2016/02/12) PMD refactoring. Collections.synchronizedMap で対応。
    102         *
    103         * @param   query DB検索(SQL)文字列
    104         * @param       dbid  データベース接続先ID
    105         * @param       lang  リソースを使用する場合の言語
    106         *
    107         * @return  Selectionオブジェクト
    108         */
    109        public static Selection newDBRadioSelection( final String query,final String dbid,final String lang ) {
    110                final String key = query+dbid+lang;
    111
    112                // 6.4.3.1 (2016/02/12) v は、Selection オブジェクト
    113                // Selection select = DB_RADIO_MAP.get( key );
    114                // Map#compute ： 戻り値は、新しい値。追加有り、置換有り、削除有り
    115                return DB_RADIO_MAP.compute( key ,(k,v) ->
    116                                                v == null || v.isTimeOver() ? new Selection_DBRADIO( query,dbid,lang ) : v );
    117        }
    118
    119        /**
    120         * 各種Selectionオブジェクトを構築します。
    121         * ここでは、Selectionオブジェクトのタイプが、(KEYVAL,HM,NUM,YMD)について作成されます。
    122         * ここで作成されるオブジェクトは、この、SelectionFactoryではキャッシュしません。
    123         * 各RendererやEditorが共有されているので、そちらでキャッシュされています。
    124         * type が指定のキーワード以外の場合は、Exception が返されます。
    125         * ※ type="NULL" も使用可能です。これは、どんな場合でも、引数の param を返す Selection
    126         * オブジェクトを返します。内部的に、CodeDataが存在しない場合など、エラーメッセージを
    127         * 引数に与えて修正を促すようなケースで使用します。
    128         * ※ type="MENU" を指定した場合は、KBMENU(type=KEYVAL) を構築します。
    129         * パラメータは、キー：値 の組み合わせの文字列です。
    130         *
    131         * ※ 指定のタイプが存在しない場合、HybsSystemException が throw されます。
    132         *
    133         * @og.rev 5.7.3.0 (2014/02/07) 新規作成
    134         * @og.rev 6.0.4.0 (2014/11/28) type に、MENU を指定できるように変更
    135         * @og.rev 6.2.6.0 (2015/06/19) type別Selectionの場合、ラベルリソースを使用する為、言語を引数で渡す。
    136         * @og.rev 6.3.4.0 (2015/08/01) Selection_HM の引数から、lang 属性を削除します。
    137         * @og.rev 7.2.4.0 (2020/05/11) Selection_FILES 追加
    138         *
    139         * @param   type  Selectionオブジェクトのタイプ(KEYVAL,MENU,HM,NUM,YMD,MENU)
    140         * @param       editPrm type別のパラメータ文字列
    141         * @param       lang  言語
    142         *
    143         * @return  Selectionオブジェクト
    144         */
    145        public static Selection newSelection( final String type,final String editPrm,final String lang ) {
    146                Selection select = null;
    147                if( "KEYVAL".equalsIgnoreCase( type ) || "MENU".equalsIgnoreCase( type ) ) {
    148                        select = new Selection_KEYVAL( editPrm,lang );  // 6.2.6.0 (2015/06/19)
    149                }
    150                else if( "HM".equalsIgnoreCase( type ) ) {
    151                        select = new Selection_HM( editPrm );                   // 6.3.4.0 (2015/08/01)
    152                }
    153                else if( "NUM".equalsIgnoreCase( type ) ) {
    154                        select = new Selection_NUM( editPrm );                  // 6.3.4.0 (2015/08/01)
    155                }
    156                else if( "YMD".equalsIgnoreCase( type ) ) {
    157                        select = new Selection_YMD( editPrm );                  // 6.3.4.0 (2015/08/01)
    158                }
    159                else if( "FILES".equalsIgnoreCase( type ) ) {
    160                        select = new Selection_FILES( editPrm );                // 7.2.4.0 (2020/05/11)
    161                }
    162                else if( "NULL".equalsIgnoreCase( type ) ) {
    163                        select = new Selection_NULL( editPrm );                 // 6.3.4.0 (2015/08/01)
    164                }
    165                else {
    166                        final String errMsg = "指定のタイプ[" + type + "]が、存在しません。" + CR
    167                                                                        + "  タイプ一覧=[KEYVAL,MENU,HM,NUM,YMD]" + CR
    168                                                                        + "  param=[" + editPrm + "]" + CR;
    169                        throw new HybsSystemException( errMsg );
    170                }
    171
    172                return select;
    173        }
    174
    175        /**
    176         * 各種Selectionオブジェクトを構築します。
    177         * ここでは、Selectionオブジェクトのタイプが、(MENU,RADIO)について作成されます。
    178         * ここで作成されるオブジェクトは、この、SelectionFactoryではキャッシュしません。
    179         * 各RendererやEditorが共有されているので、そちらでキャッシュされています。
    180         * type が指定のキーワード以外の場合は、Exception が返されます。
    181         * codeData オブジェクトが null の場合は、Selectionオブジェクト は null が返されます。
    182         *
    183         * ※ 指定のタイプが存在しない場合、HybsSystemException が throw されます。
    184         *
    185         * @og.rev 5.7.3.0 (2014/02/07) 新規作成
    186         * @og.rev 6.2.0.0 (2015/02/27) キー:ラベル形式で表示するかどうかを、指定できるようにします。
    187         * @og.rev 6.2.2.4 (2015/04/24) BITBOX 新規追加
    188         * @og.rev 6.4.4.0 (2016/03/11) CHBOX2は、コードリソースも使用できるように変更。
    189         *
    190         * @param   type  Selectionオブジェクトのタイプ(MENU,RADIO)
    191         * @param       codeData CodeDataオブジェクト
    192         * @param       addKeyLabel キー:ラベル形式で表示するかどうか[true/false/null]
    193         *
    194         * @return  Selectionオブジェクト(codeData オブジェクトが null の場合は、null)
    195         */
    196        public static Selection newSelection( final String type,final CodeData codeData,final String addKeyLabel ) {
    197                Selection select = null;
    198                if( codeData != null ) {
    199                        if( "MENU".equalsIgnoreCase( type ) ) {
    200                                select = new Selection_CODE( codeData,addKeyLabel );
    201                        }
    202                        else if( "RADIO".equalsIgnoreCase( type ) ) {
    203                                select = new Selection_RADIO( codeData );
    204                        }
    205                        else if( "CHBOX".equalsIgnoreCase( type ) ) {                   // 6.4.4.0 (2016/03/11)
    206                                select = new Selection_CHBOX( codeData );
    207                        }
    208                        // 6.2.2.4 (2015/04/24) BITBOX 新規追加
    209                        else if( "BITBOX".equalsIgnoreCase( type ) ) {
    210                                select = new Selection_BITBOX( codeData );
    211                        }
    212                        else {
    213                                final String errMsg = "指定のタイプ[" + type + "]が、存在しません。タイプ一覧=[MENU,RADIO,CHBOX,BITBOX]" + CR ;
    214                                throw new HybsSystemException( errMsg );
    215                        }
    216                }
    217
    218                return select;
    219        }
    220
    221        /**
    222         * Selectionオブジェクトをプールからすべて削除します。
    223         * システム全体を初期化するときや、動作が不安定になったときに行います。
    224         * プールの方法自体が,一種のキャッシュ的な使いかたしかしていない為,
    225         * 実行中でも、いつでもプールを初期化できます。
    226         *
    227         * @og.rev 4.3.3.6 (2008/11/15) DBRadioMap追加
    228         * @og.rev 6.4.3.1 (2016/02/12) PMD refactoring. Collections.synchronizedMap で対応。
    229         */
    230        public static void clear() {
    231                // synchronized( codeMap ) { codeMap.clear(); }
    232                DB_MAP.clear();
    233                DB_RADIO_MAP.clear();   // 4.3.3.6 (2008/11/15)
    234        }
    235}