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        /**
098         * DB検索(SQL)文字列より、データベースSelectionオブジェクトを構築します。
099         * Selection_DB では、検索行毎のクエリーがあるため、name + query でキャッシュします。
100         *
101         * @og.rev 4.3.3.6 (2008/11/15) 新規作成
102         * @og.rev 6.4.3.1 (2016/02/12) PMD refactoring. Collections.synchronizedMap で対応。
103         *
104         * @param   query DB検索(SQL)文字列
105         * @param       dbid  データベース接続先ID
106         * @param       lang  リソースを使用する場合の言語
107         *
108         * @return  Selectionオブジェクト
109         */
110        public static Selection newDBRadioSelection( final String query,final String dbid,final String lang ) {
111                final String key = query+dbid+lang;
112
113                // 6.4.3.1 (2016/02/12) v は、Selection オブジェクト
114                // Selection select = DB_RADIO_MAP.get( key );
115                // Map#compute : 戻り値は、新しい値。追加有り、置換有り、削除有り
116                return DB_RADIO_MAP.compute( key ,(k,v) ->
117                                                v == null || v.isTimeOver() ? new Selection_DBRADIO( query,dbid,lang ) : v );
118
119        }
120
121        /**
122         * 各種Selectionオブジェクトを構築します。
123         * ここでは、Selectionオブジェクトのタイプが、(KEYVAL,HM,NUM,YMD)について作成されます。
124         * ここで作成されるオブジェクトは、この、SelectionFactoryではキャッシュしません。
125         * 各RendererやEditorが共有されているので、そちらでキャッシュされています。
126         * type が指定のキーワード以外の場合は、Exception が返されます。
127         * ※ type="NULL" も使用可能です。これは、どんな場合でも、引数の param を返す Selection
128         * オブジェクトを返します。内部的に、CodeDataが存在しない場合など、エラーメッセージを
129         * 引数に与えて修正を促すようなケースで使用します。
130         * ※ type="MENU" を指定した場合は、KBMENU(type=KEYVAL) を構築します。
131         * パラメータは、キー:値 の組み合わせの文字列です。
132         *
133         * ※ 指定のタイプが存在しない場合、HybsSystemException が throw されます。
134         *
135         * @og.rev 5.7.3.0 (2014/02/07) 新規作成
136         * @og.rev 6.0.4.0 (2014/11/28) type に、MENU を指定できるように変更
137         * @og.rev 6.2.6.0 (2015/06/19) type別Selectionの場合、ラベルリソースを使用する為、言語を引数で渡す。
138         * @og.rev 6.3.4.0 (2015/08/01) Selection_HM の引数から、lang 属性を削除します。
139         *
140         * @param   type  Selectionオブジェクトのタイプ(KEYVAL,MENU,HM,NUM,YMD,MENU)
141         * @param       editPrm type別のパラメータ文字列
142         * @param       lang  言語
143         *
144         * @return  Selectionオブジェクト
145         */
146        public static Selection newSelection( final String type,final String editPrm,final String lang ) {
147                Selection select = null;
148                if( "KEYVAL".equalsIgnoreCase( type ) || "MENU".equalsIgnoreCase( type ) ) {
149                        select = new Selection_KEYVAL( editPrm,lang );  // 6.2.6.0 (2015/06/19)
150                }
151                else if( "HM".equalsIgnoreCase( type ) ) {
152                        select = new Selection_HM( editPrm );                   // 6.3.4.0 (2015/08/01)
153                }
154                else if( "NUM".equalsIgnoreCase( type ) ) {
155                        select = new Selection_NUM( editPrm );                  // 6.3.4.0 (2015/08/01)
156                }
157                else if( "YMD".equalsIgnoreCase( type ) ) {
158                        select = new Selection_YMD( editPrm );                  // 6.3.4.0 (2015/08/01)
159                }
160                else if( "NULL".equalsIgnoreCase( type ) ) {
161                        select = new Selection_NULL( editPrm );                 // 6.3.4.0 (2015/08/01)
162                }
163                else {
164                        final String errMsg = "指定のタイプ[" + type + "]が、存在しません。" + CR
165                                                                        + "  タイプ一覧=[KEYVAL,MENU,HM,NUM,YMD]" + CR
166                                                                        + "  param=[" + editPrm + "]" + CR;
167                        throw new HybsSystemException( errMsg );
168                }
169
170                return select;
171        }
172
173        /**
174         * 各種Selectionオブジェクトを構築します。
175         * ここでは、Selectionオブジェクトのタイプが、(MENU,RADIO)について作成されます。
176         * ここで作成されるオブジェクトは、この、SelectionFactoryではキャッシュしません。
177         * 各RendererやEditorが共有されているので、そちらでキャッシュされています。
178         * type が指定のキーワード以外の場合は、Exception が返されます。
179         * codeData オブジェクトが null の場合は、Selectionオブジェクト は null が返されます。
180         *
181         * ※ 指定のタイプが存在しない場合、HybsSystemException が throw されます。
182         *
183         * @og.rev 5.7.3.0 (2014/02/07) 新規作成
184         * @og.rev 6.2.0.0 (2015/02/27) キー:ラベル形式で表示するかどうかを、指定できるようにします。
185         * @og.rev 6.2.2.4 (2015/04/24) BITBOX 新規追加
186         * @og.rev 6.4.4.0 (2016/03/11) CHBOX2は、コードリソースも使用できるように変更。
187         *
188         * @param   type  Selectionオブジェクトのタイプ(MENU,RADIO)
189         * @param       codeData CodeDataオブジェクト
190         * @param       addKeyLabel キー:ラベル形式で表示するかどうか[true/false/null]
191         *
192         * @return  Selectionオブジェクト(codeData オブジェクトが null の場合は、null)
193         */
194        public static Selection newSelection( final String type,final CodeData codeData,final String addKeyLabel ) {
195                Selection select = null;
196                if( codeData != null ) {
197                        if( "MENU".equalsIgnoreCase( type ) ) {
198                                select = new Selection_CODE( codeData,addKeyLabel );
199                        }
200                        else if( "RADIO".equalsIgnoreCase( type ) ) {
201                                select = new Selection_RADIO( codeData );
202                        }
203                        else if( "CHBOX".equalsIgnoreCase( type ) ) {                   // 6.4.4.0 (2016/03/11)
204                                select = new Selection_CHBOX( codeData );
205                        }
206                        // 6.2.2.4 (2015/04/24) BITBOX 新規追加
207                        else if( "BITBOX".equalsIgnoreCase( type ) ) {
208                                select = new Selection_BITBOX( codeData );
209                        }
210                        else {
211                                final String errMsg = "指定のタイプ[" + type + "]が、存在しません。タイプ一覧=[MENU,RADIO,CHBOX,BITBOX]" + CR ;
212                                throw new HybsSystemException( errMsg );
213                        }
214                }
215
216                return select;
217        }
218
219        /**
220         * Selectionオブジェクトをプールからすべて削除します。
221         * システム全体を初期化するときや、動作が不安定になったときに行います。
222         * プールの方法自体が,一種のキャッシュ的な使いかたしかしていない為,
223         * 実行中でも、いつでもプールを初期化できます。
224         *
225         * @og.rev 4.3.3.6 (2008/11/15) DBRadioMap追加
226         * @og.rev 6.4.3.1 (2016/02/12) PMD refactoring. Collections.synchronizedMap で対応。
227         */
228        public static void clear() {
229                // synchronized( codeMap ) { codeMap.clear(); }
230                DB_MAP.clear();
231                DB_RADIO_MAP.clear();   // 4.3.3.6 (2008/11/15)
232        }
233}