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.develop;
017
018import java.util.Locale;
019import java.util.regex.Pattern;
020import java.util.regex.Matcher;
021
022import static org.opengion.fukurou.util.StringUtil.isNull;
023
024/**
025 * GF91.GF92テーブルとJSPの変換オブジェクト
026 *
027 *
028 * @author Takeshi.Takada
029 *
030 */
031public final class JspConvertEntity {
032        // 5.5.2.6 (2012/05/25) findbugs対応
033        private static final String[] DBKEY = {"SYSTEM_ID","PGID","NMSYORI","SEQ","CLM","CLM_NAME","KBACCS",
034                                                                                        "MUST","DEFAULT_VAL","TABLE_NAME","ZOKUSEI","SETU",
035                                                                                        "NMSYS","NMPG","HPGID","USE_ORDER","AS_CLM","JOINTYPE","AS_TABLE","CLS_NAME"};
036
037        // 5.1.1.0 (2009/12/01) データのアクセス用の配列番号のID
038        private static final int PGID                   = 1;            // COMMENTのみ
039        private static final int NMSYORI                = 2;
040 //     private static final int SEQ                    = 3;            // 未使用
041        private static final int CLM                    = 4;
042        private static final int CLM_NAME               = 5;            // 5.6.4.4 (2013/05/31) カラム名 追加
043 //     private static final int KBACCS                 = 6;            // 未使用
044        private static final int MUST                   = 7;
045        private static final int DEFAULT_VAL    = 8;
046        private static final int TABLE_NAME             = 9;
047        private static final int ZOKUSEI                = 10;
048 //     private static final int SETU                   = 11;           // 未使用
049        private static final int NMSYS                  = 12;           // COMMENTのみ
050        private static final int NMPG                   = 13;           // COMMENTのみ
051 //     private static final int HPGID                  = 14;           // 未使用
052        private static final int USE_ORDER              = 15;
053        private static final int AS_CLM                 = 16;
054        private static final int JOINTYPE               = 17;
055        private static final int AS_TABLE               = 18;
056        private static final int CLS_NAME               = 19;
057
058        private final String _type;                             // GF92.NMSYORI
059        private final String _column_name;              // GF92.CLM
060        private final String _clm_name_ja;              // 5.6.4.4 (2013/05/31) カラム名 追加(GF92にはなく、リソースから変換した名称)
061        private final String _table_name;               // GF92.TABLE_NAME GF91.TABLE_NAME
062        private final String _as_table_name;    // GF91.AS_TABLE
063        private final String _as_column_name;   // GF92.AS_CLM
064        private final String _default_value;    // GF92.DEFAULT_VAL
065        private final String _remarks;                  // GF92.ZOKUSEI
066        private final String _must;                             // GF92.MUST
067
068        private final String _nmsys;                    // GF90.NMSYS
069        private final String _pgid;                             // GF92.PGID
070        private final String _nmpg      ;                       // GF90.NMPG
071
072        private final String _use_order;                // GF92.USE_ORDER
073        private final boolean _is_number;               // 
074        private final String _join_type;                // GF92.JOIN_TYPE
075
076        private final JspConvertEntity _join_column;
077
078        /**
079         * ファクトリクラス
080         * QUERY、JOIN、CONST は、ZOKUSEIデータが 存在しないとき、作成しません。
081         * ここでは、null を返します。
082         *
083         * @param       data    (GF92.NMSYORI)
084         * @param       clmNo   カラム番号配列
085         *
086         * @return 新しく作成された JspConvertEntity
087         */
088        public static JspConvertEntity newInstance( final String[] data, final int[] clmNo ) {
089                final String nmSyori = data[clmNo[NMSYORI]];
090                final String zokusei = data[clmNo[ZOKUSEI]];
091
092                // 6.4.1.1 (2016/01/16) PMD refactoring. A method should have only one exit point, and that should be the last statement in the method
093                return isNull( zokusei ) && ( "QUERY".equals(nmSyori) || "JOIN".equals(nmSyori) || "CONST".equals(nmSyori) )
094                                        ? null : new JspConvertEntity( data, clmNo ) ;
095
096        }
097
098        /**
099         * コンストラクタ
100         *
101         * @og.rev 5.6.4.4 (2013/05/31) カラム名 追加
102         *
103         * @param       data    データ配列
104         * @param       clmNo   カラムの配列番号
105         */
106        private JspConvertEntity( final String[] data, final int[] clmNo ) {
107                _type                   =       data[clmNo[NMSYORI]];           // GF92.NMSYORI
108                _table_name             =       data[clmNo[TABLE_NAME]];        // GF92.TABLE_NAME GF91.TABLE_NAME
109                _as_table_name  =       data[clmNo[AS_TABLE]];          // GF91.AS_TABLE
110                _column_name    =       data[clmNo[CLM]];                       // GF92.CLM
111                _clm_name_ja    =       data[clmNo[CLM_NAME]];          // 5.6.4.4 (2013/05/31) カラム名
112                _as_column_name =       data[clmNo[AS_CLM]];            // GF92.AS_CLM
113                _default_value  =       data[clmNo[DEFAULT_VAL]];       // GF92.DEFAULT_VAL
114                _remarks                =       data[clmNo[ZOKUSEI]];           // GF92.ZOKUSEI
115                _must                   =       data[clmNo[MUST]];                      // GF92.MUST
116                _use_order              =       data[clmNo[USE_ORDER]];         // GF92.USE_ORDER
117                _is_number              =       "NUMBER".equals( data[clmNo[CLS_NAME]]);                // 
118                _join_type              =       data[clmNo[JOINTYPE]];          // GF92.JOIN_TYPE
119
120                _nmsys                  =       data[clmNo[NMSYS]];                     // GF90.NMSYS
121                _pgid                   =       data[clmNo[PGID]];                      // GF92.PGID
122                _nmpg                   =       data[clmNo[NMPG]];                      // GF90.NMPG
123
124                if( "JOIN".equals(_type) ) {
125                        _join_column = createLeftTable( _remarks );
126                }
127                else {
128                        _join_column = null;
129                }
130        }
131
132        /**
133         * コンストラクタ(通常利用していない)
134         * createLeftTable( String zokusei ) から呼び出す、内部だけで利用しているコンストラクタ
135         *
136         * @og.rev 5.6.4.4 (2013/05/31) カラム名 追加
137         *
138         * @param       type                    処理名(GF92.NMSYORI)
139         * @param       table_name              テーブル名(GF92.TABLE_NAME,GF91.TABLE_NAME)
140         * @param       as_table_name   テーブル別名(GF91.AS_TABLE)
141         * @param       column_name             カラム名(GF92.CLM)
142         */
143        private JspConvertEntity( final String type, final String table_name, final String as_table_name, final String column_name ) {
144                _type                   =       type;                           // GF92.NMSYORI
145                _table_name             =       table_name;                     // GF92.TABLE_NAME GF91.TABLE_NAME
146                _as_table_name  =       as_table_name;          // GF91.AS_TABLE
147                _column_name    =       column_name;            // GF92.CLM
148                _clm_name_ja    =       null;                           // 5.6.4.4 (2013/05/31) カラム名
149                _as_column_name =       null;                           // GF92.AS_CLM
150                _default_value  =       null;                           // GF92.DEFAULT_VAL
151                _remarks                =       null;                           // GF92.ZOKUSEI
152                _must                   =       null;                           // GF92.MUST
153                _use_order              =       null;                           // GF92.USE_ORDER
154                _is_number              =       false;                          // 
155                _join_type              =       null;                           // GF92.JOIN_TYPE
156                _join_column    =       null;
157                _nmsys                  =       null;                           // GF90.NMSYS
158                _pgid                   =       null;                           // GF92.PGID
159                _nmpg                   =       null;                           // GF90.NMPG
160        }
161
162        /**
163         * データのアクセス用のカラム名配列を返します。
164         * これを利用して、カラム名の番号を取得し、JspConvertEntity#newInstance( String[],int[] ) の
165         * 2番目の引数に指定します。
166         *
167         * @og.rev 5.5.2.6 (2012/05/25) findbugs対応。JspConvertEntity.DBKEY を、JspConvertEntity.getDBKEY() に変更。
168         *
169         * @return      DBKEY配列のクローン
170         * @og.rtnNotNull
171         */
172        public static String[] getDBKEY() {
173                return DBKEY.clone();
174        }
175
176        /**
177         * データのタイプを取得。(GF92.NMSYORI)
178         *
179         * @return      データのタイプ
180         */
181        public String getType(){
182                return _type;
183        }
184
185        /**
186         * テーブル名を取得。(GF92.TABLE_NAME GF91.TABLE_NAME)
187         *
188         * @return      テーブル名
189         */
190        public String getTableName(){
191                return _table_name;
192        }
193
194        /**
195         * カラム名を取得。(GF92.CLM)
196         *
197         * @return      カラム名
198         */
199        public String getColumnName(){
200                return _column_name;
201        }
202
203        /**
204         * カラム名称を取得。
205         * 
206         * カラム名称は、GF92.CLM をキーにリソースを検索した結果の日本語になります。SELECT文のコメントに使います。
207         *
208         * @og.rev 5.6.4.4 (2013/05/31) カラム名 追加
209         *
210         * @return      カラム名称
211         */
212        public String getColumnCommentName(){
213                return _clm_name_ja;
214        }
215
216        /**
217         * テーブル名が先頭に付いたカラム名を取得。
218         *
219         * @return      カラム名(テーブル名付き)
220         * @og.rtnNotNull
221         */
222        public String getFullColumnName(){
223                String preffix = "";
224
225                if( isNull( _as_table_name ) ) {
226                        preffix = _table_name;
227                }
228                else {
229                        preffix = _as_table_name;
230                }
231                //集計関数が利用されている場合は、関数別に特別な処理を実装する必要がある。
232                //現在は、テーブル名やテーブル別名を付加せずにスルーする様に実装してあります。
233                Matcher matcher = null;
234                for( final JspEnumeration.TREATS_STRING_FUNCTIONS func : JspEnumeration.TREATS_STRING_FUNCTIONS.values()){
235                        final String k = func.toString();
236                        matcher = Pattern.compile("(((\\s*?)|\\()" + k + "(\\s+?))|(((\\s*?)|\\()"  + k.toLowerCase( Locale.JAPAN ) + "(\\s+?))").matcher( _column_name );
237                        if( matcher.find() ) {
238                                return func.update( _column_name ,  new String[]{ } );
239                        }
240                }
241                return preffix + "." + _column_name;
242        }
243
244        /**
245         * 結合先のカラム情報を取得。
246         *
247         * @return      結合先のカラム
248         */
249        public JspConvertEntity getJoinColumn(){
250                return _join_column;
251        }
252
253        /**
254         * テーブルに付ける別名を取得(GF91.AS_TABLE)。
255         *
256         * @return      テーブルに付ける別名
257         */
258        public String getAsTableName(){
259                return _as_table_name;
260        }
261
262        /**
263         * カラムに付ける別名を取得(GF92.AS_CLM)。
264         *
265         * @return      カラムに付ける別名
266         */
267        public String getAsColumnName(){
268                return _as_column_name;
269        }
270
271        /**
272         * Select句ですぐに利用可能なカラム名を取得。
273         *
274         * @return      カラム名
275         * @og.rtnNotNull
276         */
277        public String getSelectPartColumnName(){
278                if( isNull( _remarks ) || "DISP".equalsIgnoreCase( _remarks ) ) {
279                        if( isNull( _as_column_name ) ) {
280                                return getFullColumnName();
281                        }
282                        else {
283                                return getFullColumnName() + " as " + _as_column_name;
284                        }
285                }
286                else {
287                        if( isNull( _as_column_name ) ) {
288                                return _remarks + "(" + getFullColumnName() + ")";
289                        }
290                        else {
291                                return _remarks + "(" + getFullColumnName() + ") as " + _as_column_name;
292                        }
293                }
294        }
295
296        /**
297         * From句ですぐに利用可能なカラム名を取得。
298         *
299         * @return      別名のついたテーブル名
300         */
301        public String getFromPartTableName(){
302                // 6.4.1.1 (2016/01/16) PMD refactoring. A method should have only one exit point, and that should be the last statement in the method
303                return isNull( _as_table_name ) ? _table_name : _table_name + " " + _as_table_name;
304
305        }
306
307        /**
308         * 初期値を取得。(GF92.DEFAULT_VAL)
309         *
310         * @return      初期値
311         */
312        public String getDefaultValue(){
313                return _default_value;
314        }
315
316        /**
317         * 属性内容を取得。(GF92.ZOKUSEI)
318         *
319         * @return      属性内容
320         */
321        public String getRemarks(){
322                return _remarks;
323        }
324
325        /**
326         * 必須を取得。(GF92.MUST)
327         *
328         * @return      必須
329         */
330        public String getMust(){
331                return _must;
332        }
333
334        /**
335         * 並び替え設定か否かを判定(GF92.USE_ORDER)。
336         *
337         * @return      判定結果
338         */
339        public String getUseOrder(){
340                return _use_order;
341        }
342
343        /**
344         * 数値項目か否かを判定。
345         *
346         * @return      判定結果
347         */
348        public boolean isNumber(){
349                return _is_number;
350        }
351
352        /**
353         * システムの名称を取得します(GF90.NMSYS)。
354         *
355         * @return      名称
356         */
357        public String getNmSys(){
358                return _nmsys;
359        }
360
361        /**
362         * プログラムIDを取得します。(GF92.PGID)
363         *
364         * @return      プログラムID
365         */
366        public String getPgid(){
367                return _pgid;
368        }
369
370        /**
371         * プログラムの名称を取得します(GF90.NMPG)。
372         *
373         * @return      名称
374         */
375        public String getNmpg(){
376                return _nmpg;
377        }
378
379        /**
380         * 外部結合かを判定(GF92.JOIN_TYPE)。
381         *
382         * @return      判定結果
383         */
384        public String getJoinType(){
385                return _join_type;
386        }
387
388        /**
389         * 外部結合かを判定(GF92.JOIN_TYPE)。
390         *
391         * @param       zokusei 属性情報
392         *
393         * @return      外部結合のJspConvertEntityオブジェクト
394         */
395        private JspConvertEntity createLeftTable( final String zokusei ){
396                JspConvertEntity rgt = null;
397
398                final String[] rgt_data = zokusei.split( "__" );
399                if( rgt_data.length == 3 ){
400                        final String rgt_tbl            = rgt_data[1];
401                        final String rgt_as_tbl = rgt_data[2].substring( 0 , rgt_data[2].indexOf('.') );
402                        final String rgt_clm            = rgt_data[2].substring( rgt_data[2].indexOf('.') + 1 );
403
404                        rgt = new JspConvertEntity( "JOIN",rgt_tbl,rgt_as_tbl,rgt_clm );
405                }
406
407                return rgt;
408        }
409}