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.Map;
019import java.util.WeakHashMap ;
020import java.util.Collections ;                                                                                  // 6.4.3.1 (2016/02/12) ConcurrentHashMap が使えないため。
021
022import org.opengion.fukurou.util.Cleanable;
023import org.opengion.hayabusa.common.HybsSystemException ;
024import org.opengion.hayabusa.common.SystemManager ;
025import org.opengion.hayabusa.resource.CodeData;
026import static org.opengion.fukurou.system.HybsConst.CR ;                                // 6.1.0.0 (2014/12/26)
027import static org.opengion.fukurou.system.HybsConst.BUFFER_MIDDLE;              // 6.1.0.0 (2014/12/26) refactoring
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 ) );
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 ) );
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}