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