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.HashMap;
019import java.util.HashSet;
020import java.util.Map;
021import java.util.Set;
022
023import org.opengion.fukurou.util.StringUtil;
024
025/**
026 * エディット設定情報を管理するためのデータ管理クラスです。
027 * ここで管理される各パラメーターの意味は以下の通りです。
028 * (各インデックス番号は、内部的に管理されているインデックス番号を意味します)
029 *
030 * ・0:エディット名
031 *       このエディット設定オブジェクトの名称です。
032 * ・1:表示カラム
033 *       表示対象となるカラム一覧です。カンマ区切りで指定します。
034 *       この一覧には、非表示のカラムも合わせて管理され、非表示カラムについては、
035 *       カラム名の先頭に"!"をつけます。
036 *       例) AAA,!BBB,CCC ⇒ AAA,CCCの順に表示(BBBは非表示)
037 * ・2:集計カラム
038 *       各値をSUMする対象となるカラムです。(カンマ区切りで複数指定が可能)
039 *       ここで指定されたカラムは数値型である必要があります。
040 *       SQL構文における、SUM関数の引数として指定するカラムに相当します。
041 * ・3:グループカラム
042 *       集計カラムの各値をグルーピングするためのカラムです。(カンマ区切りで複数指定が可能)
043 *       SQL構文における、GROUP BYに指定するカラムに相当します。
044 * ・4:小計カラム
045 *       集計カラムの各値に対し、小計行を付加するためのブレイクキーを指定します。(カンマ区切りで複数指定が可能)
046 * ・5:合計カラム
047 *       集計カラムの各値に対し、合計行を付加するためのブレイクキーを指定します。(カンマ区切りで複数指定が可能)
048 * ・6:総合計フラグ
049 *       集計カラムの各値に対し、総合計行を付加するかどうかを指定します。(0以外:追加する 0:追加しない)
050 * ・7:表示順カラム
051 *       データの表示順をその順番にカンマ区切りで指定します。
052 *       カラム名の先頭に"!"をつけた場合は、そのカラムは降順で表示されます。
053 *       SQL構文における、orderby句に相当します。
054 * ・8:共通フラグ
055 *       このエディット設定オブジェクトが、共通(全ユーザー公開)エディットかどうかを
056 *       指定します。(0以外:共通 0:個人のみ)
057 *
058 * @og.rev 5.3.6.0 (2011/06/01) 新規追加
059 *
060 * @version  5.0
061 * @author   Hiroki Nakamura
062 * @since    JDK6.0,
063 */
064public class DBEditConfig {
065
066        private static final int EDIT_KEY_NAME          = 0;
067        private static final int EDIT_KEY_VIEW          = 1;
068        private static final int EDIT_KEY_SUM           = 2;
069        private static final int EDIT_KEY_GROUP         = 3;
070        private static final int EDIT_KEY_SUBTOTAL      = 4;
071        private static final int EDIT_KEY_TOTAL         = 5;
072        private static final int EDIT_KEY_GRANDTOTAL= 6;
073        private static final int EDIT_KEY_ORDERBY       = 7;
074        private static final int EDIT_KEY_COMMON        = 8;
075
076        private static final String[] EDIT_KEYS
077                = { "NAME", "VIEW", "SUM", "GROUP", "SUBTOTAL", "TOTAL", "GRANDTOTAL", "ORDERBY", "COMMON" };
078
079        private static final int EDIT_KEYS_LENGTH       = EDIT_KEYS.length;
080
081        private final String[] editVals = new String[EDIT_KEYS_LENGTH];
082
083        private int sumClmCount;
084        private int groupClmCount;
085        private int subTotalClmCount;
086        private int totalClmCount;
087        private final Map<String,String> orderMap = new HashMap<String,String>();
088        private String orderByDescClms;
089
090        /**
091         * コンストラクタ
092         *
093         * 空のエディット設定オブジェクトを構築します。
094         */
095        public DBEditConfig() {}
096
097        /**
098         * コンストラクタ
099         *
100         * 各種パラメーターを指定してエディット設定オブジェクトを構築します。
101         *
102         * @param editName エディット名称
103         * @param viewClms 画面表示カラム
104         * @param sumClms 集計カラム
105         * @param groupClms グループカラム
106         * @param subTotalClms 小計カラム
107         * @param totalClms 合計カラム
108         * @param useGrandTotal 総合計行を追加するか(1:追加する 1以外:追加しない)
109         * @param orderByClms 表示順
110         * @param isCommon 共通エディットかどうか(1:共通 1以外:個人のみ)
111         */
112        public DBEditConfig( final String editName, final String viewClms
113                                                , final String sumClms, final String groupClms
114                                                , final String subTotalClms, final String totalClms
115                                                , final String useGrandTotal, final String orderByClms
116                                                , final String isCommon ) {
117
118                editVals[EDIT_KEY_NAME]                 = editName;
119                editVals[EDIT_KEY_VIEW]                 = viewClms;
120                editVals[EDIT_KEY_SUM]                  = sumClms;
121                editVals[EDIT_KEY_GROUP]                = groupClms;
122                editVals[EDIT_KEY_SUBTOTAL]             = subTotalClms;
123                editVals[EDIT_KEY_TOTAL]                = totalClms;
124                editVals[EDIT_KEY_GRANDTOTAL]   = useGrandTotal;
125                editVals[EDIT_KEY_ORDERBY]              = orderByClms;
126                editVals[EDIT_KEY_COMMON]               = isCommon;
127
128                init();
129        }
130
131        /**
132         * コンストラクタ
133         *
134         * 各種パラメーターを配列で指定してエディット設定オブジェクトを構築します。
135         * 各パラメータの配列インデックスは、{@link #getEditKeys(String,String)}で返される
136         * キー一覧の配列インデックスと一致します。
137         * 各パラメーターの意味については、クラスのJavadoc{@link DBEditConfig}を参照して下さい。
138         *
139         * @param editVals 設定値(配列)
140         * @see DBEditConfig
141         * @see #getEditKeys(String,String)
142         **/
143        public DBEditConfig( final String[] editVals ) {
144                System.arraycopy( editVals, 0, this.editVals, 0, editVals.length );
145                init();
146        }
147
148        /**
149         * エディット設定オブジェクト作成時の初期化処理です。
150         * コンストラクタの引数に基づき内部変数の初期設定を行います。
151         */
152        private void init() {
153                sumClmCount = StringUtil.csv2Array( editVals[EDIT_KEY_SUM] ).length;
154                groupClmCount = StringUtil.csv2Array( editVals[EDIT_KEY_GROUP] ).length;
155                subTotalClmCount = StringUtil.csv2Array( editVals[EDIT_KEY_SUBTOTAL] ).length;
156                totalClmCount = StringUtil.csv2Array( editVals[EDIT_KEY_TOTAL] ).length;
157
158                if( editVals[EDIT_KEY_ORDERBY] != null ) {
159                        StringBuilder buf = new StringBuilder();
160                        String[] ary = StringUtil.csv2Array( editVals[EDIT_KEY_ORDERBY] );
161                        for( int i=0; i<ary.length ;i++ ) {
162                                String str = ary[i];
163                                if( str.startsWith( "!" ) ) {
164                                        str = str.substring( 1 );
165                                        if( buf.length() > 0 ) { buf.append( "," ); }
166                                        buf.append( str );
167                                }
168                                orderMap.put( str, String.valueOf( i+1 ) );
169                        }
170                        orderByDescClms = buf.toString();
171                }
172                else {
173                        orderByDescClms = null;
174                }
175        }
176
177        /**
178         * キー配列から画面IDとエディット名称のペアの一覧を取り出します。
179         *
180         * キー配列から"EDIT_NAME_"で始まるキーを検索し、"EDIT_NAME_(画面ID)_(エディット名)"
181         * と言う形式に基づき、画面IDとエディット名称のペアを取り出します。
182         *
183         * 画面IDとエディット名称は配列として保存され(インデックス番号は 0:画面ID、1:エディット名)
184         * その一覧がされらに配列に格納されて返されます。
185         *
186         * @param keys キー配列
187         *
188         * @return 画面IDとエディット名称のペアの一覧
189         */
190        public static String[][] getKeySet( final String[] keys ) {
191                if( keys == null || keys.length == 0 ) { return null; }
192
193                Set<String[]> keySet = new HashSet<String[]>();
194                for( String key : keys ) {
195                        if ( key != null && key.startsWith( "EDIT_NAME_" ) ) {
196                                String guikeyEditName = key.substring( "EDIT_NAME_".length() );
197                                if( guikeyEditName.indexOf( '_' ) >= 0 ) {
198                                        String guikey = guikeyEditName.substring( 0, guikeyEditName.indexOf( '_' ) );
199                                        String editName = guikeyEditName.substring( ( guikey + "_" ).length() );
200                                        if( guikey != null && guikey.length() > 0 && editName != null && editName.length() > 0 ) {
201                                                String[] set = { guikey, editName };
202                                                keySet.add( set );
203                                        }
204                                }
205                        }
206                }
207                return keySet.toArray( new String[keySet.size()][] );
208        }
209
210        /**
211         * 画面ID、エディット名をキーに、エディット設定オブジェクトの各設定値の
212         * 管理キーを指定します。
213         *
214         * エディット設定オブジェクトで管理される各キーに対して、
215         * "EDIT_[KEY]_(画面ID)_(エディット名)"というキーを生成し、これを配列にして返します。
216         *
217         * @param guikey 画面ID
218         * @param editName エディット名
219         *
220         * @return エディット設定を管理するためのキー一覧
221         */
222        public static String[] getEditKeys( final String guikey, final String editName ) {
223                String[] rtn = new String[EDIT_KEYS_LENGTH];
224                for( int i=0; i<EDIT_KEYS_LENGTH; i++ ) {
225                        rtn[i] = "EDIT_" + EDIT_KEYS[i] + "_" + guikey + "_" + editName;
226                }
227                return rtn;
228        }
229
230        /**
231         * エディット設定オブジェクトの各設定値を配列にして返します。
232         *
233         * 配列のインデックス番号は、{@link #getEditKeys(String,String)}で生成されるキーの
234         * インデックス番号と一致します。
235         *
236         * @return エディット設定オブジェクトの設定値一覧(配列)
237         * @see #getEditKeys(String,String)
238         */
239        public String[] getEditVals() {
240                String[] rtn = new String[editVals.length];
241                System.arraycopy( editVals, 0, rtn, 0, editVals.length );
242                return rtn;
243        }
244
245        /**
246         * エディット名を返します。
247         *
248         * @return エディット名
249         */
250        public String getEditName() {
251                return editVals[EDIT_KEY_NAME];
252        }
253
254        /**
255         * 表示カラム名の一覧をカンマ区切りで返します。
256         * 非表示カラムについては、カラム名の先頭に"!"をつけて返されます。
257         * 例) AAA,!BBB,CCC ⇒ AAA,CCCの順に表示(BBBは非表示)
258         *
259         * @return 表示カラム名一覧(カンマ区切り)
260         */
261        public String getViewClms() {
262                return editVals[EDIT_KEY_VIEW];
263        }
264
265        /**
266         * 集計カラムの一覧をカンマ区切りで返します。
267         *
268         * @return 集計カラムの一覧(カンマ区切)
269         */
270        public String getSumClms() {
271                return editVals[EDIT_KEY_SUM];
272        }
273
274        /**
275         * 集計処理を行うかどうかを返します。
276         * これは、集計カラムが指定されているか、と同じ意味です。
277         *
278         * @return true:対象 false:非対象
279         */
280        public boolean useSum() {
281                return editVals[EDIT_KEY_SUM] != null && editVals[EDIT_KEY_SUM].length() > 0 ;
282        }
283
284        /**
285         * 指定されたカラムが集計対象のカラムかどうかを返します。
286         *
287         * @param clm カラム
288         *
289         * @return true:対象 false:非対象
290         */
291        public boolean isSumClm( final String clm ) {
292                if( clm == null || editVals[EDIT_KEY_SUM] == null ) { return false; }
293                return ( ","+editVals[EDIT_KEY_SUM]+"," ).indexOf( ","+clm+"," ) >= 0 ;
294        }
295
296        /**
297         * 集計カラムのカラム数を返します。
298         *
299         * @return 集計カラムのカラム数
300         */
301        public int getSumClmCount() {
302                return sumClmCount;
303        }
304
305        /**
306         * グループカラムの一覧をカンマ区切りで返します。
307         *
308         * @return グループカラムの一覧(カンマ区切)
309         */
310        public String getGroupClms() {
311                return editVals[EDIT_KEY_GROUP];
312        }
313
314        /**
315         * グループ処理を行うかどうかを返します。
316         * これは、グループカラムが指定されているか、と同じ意味です。
317         *
318         * @return true:対象 false:非対象
319         */
320        public boolean useGroup() {
321                return editVals[EDIT_KEY_GROUP] != null && editVals[EDIT_KEY_GROUP].length() > 0 ;
322        }
323
324        /**
325         * 指定されたカラムがグループ対象のカラムかどうかを返します。
326         *
327         * @param clm カラム
328         *
329         * @return true:対象 false:非対象
330         */
331        public boolean isGroupClm( final String clm ) {
332                if( clm == null || editVals[EDIT_KEY_GROUP] == null ) { return false; }
333                return ( ","+editVals[EDIT_KEY_GROUP]+"," ).indexOf( ","+clm+"," ) >= 0 ;
334        }
335
336        /**
337         * グループカラムのカラム数を返します。
338         *
339         * @return グループカラムのカラム数
340         */
341        public int getGroupClmCount() {
342                return groupClmCount;
343        }
344
345        /**
346         * 小計カラムの一覧をカンマ区切りで返します。
347         *
348         * @return 小計カラムの一覧(カンマ区切)
349         */
350        public String getSubTotalClms() {
351                return editVals[EDIT_KEY_SUBTOTAL];
352        }
353
354        /**
355         * 小計処理を行うかどうかを返します。
356         * これは、小計カラムが指定されているか、と同じ意味です。
357         *
358         * @return true:対象 false:非対象
359         */
360        public boolean useSubTotal() {
361                return editVals[EDIT_KEY_SUBTOTAL] != null && editVals[EDIT_KEY_SUBTOTAL].length() > 0 ;
362        }
363
364        /**
365         * 指定されたカラムが小計対象のカラムかどうかを返します。
366         *
367         * @param clm カラム
368         *
369         * @return true:対象 false:非対象
370         */
371        public boolean isSubTotalClm( final String clm ) {
372                if( clm == null || editVals[EDIT_KEY_SUBTOTAL] == null ) { return false; }
373                return ( ","+editVals[EDIT_KEY_SUBTOTAL]+"," ).indexOf( ","+clm+"," ) >= 0 ;
374        }
375
376        /**
377         * 小計カラムのカラム数を返します。
378         *
379         * @return グループカラムのカラム数
380         */
381        public int getSubTotalClmCount() {
382                return subTotalClmCount;
383        }
384
385        /**
386         * 合計カラムの一覧をカンマ区切りで返します。
387         *
388         * @return 合計カラムの一覧(カンマ区切)
389         */
390        public String getTotalClms() {
391                return editVals[EDIT_KEY_TOTAL];
392        }
393
394        /**
395         * 合計処理を行うかどうかを返します。
396         * これは、合計カラムが指定されているか、と同じ意味です。
397         *
398         * @return true:対象 false:非対象
399         */
400        public boolean useTotal() {
401                return editVals[EDIT_KEY_TOTAL] != null && editVals[EDIT_KEY_TOTAL].length() > 0 ;
402        }
403
404        /**
405         * 指定されたカラムが合計対象のカラムかどうかを返します。
406         *
407         * @param clm カラム
408         *
409         * @return true:対象 false:非対象
410         */
411        public boolean isTotalClm( final String clm ) {
412                if( clm == null || editVals[EDIT_KEY_TOTAL] == null ) { return false; }
413                return ( ","+editVals[EDIT_KEY_TOTAL]+"," ).indexOf( ","+clm+"," ) >= 0 ;
414        }
415
416        /**
417         * 合計カラムのカラム数を返します。
418         *
419         * @return グループカラムのカラム数
420         */
421        public int getTotalClmCount() {
422                return totalClmCount;
423        }
424
425        /**
426         * 総合計行を付加するかどうかを返します。
427         *
428         * @return true:対象 false:非対象
429         */
430        public boolean useGrandTotal() {
431                return StringUtil.nval( editVals[EDIT_KEY_GRANDTOTAL], false );
432        }
433
434        /**
435         * 表示順カラムをカンマ区切りで返します。
436         * カラムの並び順が表示順としての優先順になります。
437         * また、降順で表示するカラムについては、カラム名の先頭に"!"が付加されます。
438         *
439         * @return 標準順カラムの一覧(カンマ区切)
440         */
441        public String getOrderByClms() {
442                return editVals[EDIT_KEY_ORDERBY];
443        }
444
445        /**
446         * 指定されたカラムの表示順の優先番号を返します。
447         * 指定カラムが標準として指定されていない場合は、""(ゼロストリング)を返します。
448         *
449         * @param clm カラム
450         *
451         * @return 表示順の優先番号
452         */
453        public String getOrder( final String clm ) {
454                if( clm == null || editVals[EDIT_KEY_ORDERBY] == null ) { return ""; }
455
456                String rtn = orderMap.get( clm );
457                return rtn == null ? "" : rtn ;
458        }
459
460        /**
461         * 指定されたカラムの表示順指定が降順であるかどうかを返します。
462         * 標準と指定されていない場合は、falseを返します。
463         *
464         * @param clm カラム
465         *
466         * @return true:降順 false:昇順
467         */
468        public boolean isOrderByDesc( final String clm ) {
469                if( clm == null || orderByDescClms == null ) { return false; }
470                return ( ","+orderByDescClms+"," ).indexOf( ","+clm+"," ) >= 0 ;
471        }
472
473        /**
474         * 並び替え処理を行うかどうかを返します。
475         * これは、表示順カラムが指定されているか、と同じ意味です。
476         *
477         * @return true:対象 false:非対象
478         */
479        public boolean useOrderBy() {
480                return editVals[EDIT_KEY_ORDERBY] != null && editVals[EDIT_KEY_ORDERBY].length() > 0 ;
481        }
482
483        /**
484         * このエディット設定オブジェクトが、共通(全ユーザー公開)エディットか
485         * どうかを返します。
486         *
487         * @return 0以外:共通 0:個人のみ
488         */
489        public boolean isCommon() {
490                return StringUtil.nval( editVals[EDIT_KEY_COMMON], false );
491        }
492}