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.regex.Pattern;
019import java.util.Locale;
020
021import static org.opengion.fukurou.system.HybsConst.BUFFER_MIDDLE;      // 6.1.0.0 (2014/12/26) refactoring
022
023/**
024 * JSPの生成・データ取り込み処理で必要な列挙型をまとめたクラス。
025 *
026 * 主にキーワード管理とプログラム中のswitch文の削減を目的として作成。
027 *
028 *
029 * @author Takeshi.Takada
030 *
031 */
032public class JspEnumeration {
033        /**
034         * GROUP BY句を必要とする関数を列挙します。
035         *
036         * contains、searchと言った独自メソッドも実装しています。
037         *
038         */
039        public static enum GROUPING_FUNCTIONS { MAX , MIN , SUM , COUNT  ;
040
041                /**
042                 * 与えられた文字が自身に列挙された値の何れかと一致するか検証する。
043                 * 一致する場合に真を返す。
044                 * 一致しない場合に偽を返す。
045                 *
046                 * @param arg   引数
047                 * @return      検証の結果
048                 */
049                public static boolean contains( final String arg ) {
050                        for( final GROUPING_FUNCTIONS fnc : values() ){
051                                if( arg.equalsIgnoreCase( fnc.toString() ) ){
052                                        return true;
053                                }
054                        }
055                        return false;
056                }
057
058                /**
059                 * 自身に列挙されている値が与えられた文字列に含まれているか検証する。
060                 * 含まれている場合は真を返す。
061                 * 含まれていない場合は偽を返す。
062                 *
063                 * @param arg   引数
064                 * @return      検証の結果
065                 */
066                public static boolean search( final String arg ) {
067                        final String argU = arg.toUpperCase(Locale.JAPAN);
068
069                        for( final GROUPING_FUNCTIONS fnc : values() ){
070                                if( argU.indexOf( fnc.toString() ) > -1 ) {
071                                        return true;
072                                }
073                        }
074                        return false;
075                }
076        }
077
078        /**
079         * データ上はただの文字列として扱う関数を列挙します。
080         * (注:現在、列挙中の関数はOracleの内容です。)
081         *
082         */
083        public static enum TREATS_STRING_FUNCTIONS {
084                CASE ,
085                CEIL , ROUND , FLOOR , TRUNC , MOD , CHR , CONCAT , SUBSTR , INITCAP ,
086                SUBSTRB , LOWER , TRIM , LPAD   , LTRIM , UPPER , REPLACE , USER , RPAD ,
087                ASCII , LENGTH , LENGTHB , INSTR , POSITION , INSTRB  , ADD_MONTHS , DAYOFMONTH ,
088                MONTHNAME , TIMESTAMPADD , CURDATE , DAYOFWEEK , MONTHS_BETWEEN  , TIMESTAMPDIFF ,
089                CURRENT_DATE  , DAYOFYEAR , NEXT_DAY  , CURRENT_TIME  , HOUR , NOW , WEEK , CURRENT_TIMESTAMP  ,
090                LAST_DAY  , YEAR , CURTIME , MINUTE , SECOND , DAYNAME , MONTH , SYSDATE  , CAST , AVG   ,
091                CONVERT , DATABASE  , TO_CHAR  , DECODE , TO_NUMBER  , EXTRACT , TO_DATE  , GREATEST , STDDEV ,
092                INTERVAL , VARIANCE , LEAST , LOCATE , NVL  ;
093
094                /**
095                 * 関数の内容に第二引数の内容を付加する処理を実装します
096                 * 第二引数の内容
097                 * 0:カラムへ付与するテーブル名(テーブル別名)
098                 *
099                 * @param column カラム名
100                 * @param args 引数配列(可変長引数)
101                 * @return      関数を更新した結果
102                 */
103                public String update( final String column , final String... args ) {
104                        return column;
105                }
106        }
107
108        /**
109         * 演算子を列挙する。
110         *
111         * ●使用例
112         * WHERE_OPERATORS op = WHERE_OPERATORS.valueOf("eq");
113         * System.out.println(op.apply("GF92.CLM","{@CLM}",false));
114         *
115         * ●上記処理結果
116         * GF92.CLM     =       '{@CLM}'
117         *
118         */
119        public static enum WHERE_OPERATORS {
120                eq() {
121                        /**
122                         * 与えられた左辺と右辺を元に演算子付きの文字列を作成する。
123                         * 第3引数のbooleanは、trueの時に値が数値であることを意味する。
124                         *
125                         * @param       left    左辺文字列
126                         * @param       right   右辺文字列
127                         * @param       is_num  数値かどうか(trueで、数値を指定)
128                         * @return      演算子を加えた結果
129                         * @og.rtnNotNull
130                         */
131                        public String apply(final String left , final String right, final boolean is_num) {
132                                if( is_num ) {
133                                        return leftVal(left) + "=\t " + right ;
134                                }else {
135                                        return leftVal(left) + "=\t '" + right + "'";
136                                }
137                        }
138                        /**
139                         * 演算子(シンボル)の文字列配列を返します。
140                         *
141                         * @return      シンボル文字列配列
142                         * @og.rtnNotNull
143                         */
144                        public String[] symbol(){
145                                return new String[] {"="};
146                        }
147                }  ,
148                lk1() {
149                        /**
150                         * 与えられた左辺と右辺を元に演算子付きの文字列を作成する。
151                         * 第3引数のbooleanは、trueの時に値が数値であることを意味する。
152                         *
153                         * @param       left    左辺文字列
154                         * @param       right   右辺文字列
155                         * @param       is_num  数値かどうか(trueで、数値を指定)
156                         * @return      演算子を加えた結果
157                         * @og.rtnNotNull
158                         */
159                        public String apply(final String left , final String right, final boolean is_num) {
160                                return leftVal(left) + "like '" + right + "%'";
161                        }
162                        /**
163                         * 演算子(シンボル)の文字列配列を返します。
164                         *
165                         * @return      シンボル文字列配列
166                         * @og.rtnNotNull
167                         */
168                        public String[] symbol(){
169                                return new String[] {"like","","%"};
170                        }
171                }  ,
172                lk2() {
173                        /**
174                         * 与えられた左辺と右辺を元に演算子付きの文字列を作成する。
175                         * 第3引数のbooleanは、trueの時に値が数値であることを意味する。
176                         *
177                         * @param       left    左辺文字列
178                         * @param       right   右辺文字列
179                         * @param       is_num  数値かどうか(trueで、数値を指定)
180                         * @return      演算子を加えた結果
181                         * @og.rtnNotNull
182                         */
183                        public String apply(final String left , final String right, final boolean is_num) {
184                                return leftVal(left) + "like '%" + right + "'";
185                        }
186                        /**
187                         * 演算子(シンボル)の文字列配列を返します。
188                         *
189                         * @return      シンボル文字列配列
190                         * @og.rtnNotNull
191                         */
192                        public String[] symbol(){
193                                return new String[] {"like","%",""};
194                        }
195                }  ,
196                lk3() {
197                        /**
198                         * 与えられた左辺と右辺を元に演算子付きの文字列を作成する。
199                         * 第3引数のbooleanは、trueの時に値が数値であることを意味する。
200                         *
201                         * @param       left    左辺文字列
202                         * @param       right   右辺文字列
203                         * @param       is_num  数値かどうか(trueで、数値を指定)
204                         * @return      演算子を加えた結果
205                         * @og.rtnNotNull
206                         */
207                        public String apply(final String left , final String right, final boolean is_num) {
208                                return leftVal(left) + "like '%" + right + "%'";
209                        }
210                        /**
211                         * 演算子(シンボル)の文字列配列を返します。
212                         *
213                         * @return      シンボル文字列配列
214                         * @og.rtnNotNull
215                         */
216                        public String[] symbol(){
217                                return new String[] {"like","%","%"};
218                        }
219                }  ,
220                gt() {
221                        /**
222                         * 与えられた左辺と右辺を元に演算子付きの文字列を作成する。
223                         * 第3引数のbooleanは、trueの時に値が数値であることを意味する。
224                         *
225                         * @param       left    左辺文字列
226                         * @param       right   右辺文字列
227                         * @param       is_num  数値かどうか(trueで、数値を指定)
228                         * @return      演算子を加えた結果
229                         * @og.rtnNotNull
230                         */
231                        public String apply(final String left , final String right, final boolean is_num) {
232                                if( is_num ) {
233                                        return leftVal(left) + ">\t " + right;
234                                }else{
235                                        return leftVal(left) + ">\t '" + right + "'";
236                                }
237                        }
238                        /**
239                         * 演算子(シンボル)の文字列配列を返します。
240                         *
241                         * @return      シンボル文字列配列
242                         * @og.rtnNotNull
243                         */
244                        public String[] symbol(){
245                                return new String[] {">"};
246                        }
247                }  ,
248                ge() {
249                        /**
250                         * 与えられた左辺と右辺を元に演算子付きの文字列を作成する。
251                         * 第3引数のbooleanは、trueの時に値が数値であることを意味する。
252                         *
253                         * @param       left    左辺文字列
254                         * @param       right   右辺文字列
255                         * @param       is_num  数値かどうか(trueで、数値を指定)
256                         * @return      演算子を加えた結果
257                         * @og.rtnNotNull
258                         */
259                        public String apply(final String left , final String right, final boolean is_num) {
260                                if( is_num ) {
261                                        return leftVal(left) + ">=\t " + right;
262                                }else{
263                                        return leftVal(left) + ">=\t '" + right + "'";
264                                }
265                        }
266                        /**
267                         * 演算子(シンボル)の文字列配列を返します。
268                         *
269                         * @return      シンボル文字列配列
270                         * @og.rtnNotNull
271                         */
272                        public String[] symbol(){
273                                return new String[] {">="};
274                        }
275                }  ,
276                lt()  {
277                        /**
278                         * 与えられた左辺と右辺を元に演算子付きの文字列を作成する。
279                         * 第3引数のbooleanは、trueの時に値が数値であることを意味する。
280                         *
281                         * @param       left    左辺文字列
282                         * @param       right   右辺文字列
283                         * @param       is_num  数値かどうか(trueで、数値を指定)
284                         * @return      演算子を加えた結果
285                         * @og.rtnNotNull
286                         */
287                        public String apply(final String left , final String right, final boolean is_num) {
288                                if( is_num ) {
289                                        return leftVal(left) + "<\t " + right;
290                                }else {
291                                        return leftVal(left) + "<\t '" + right + "'";
292                                }
293                        }
294                        /**
295                         * 演算子(シンボル)の文字列配列を返します。
296                         *
297                         * @return      シンボル文字列配列
298                         * @og.rtnNotNull
299                         */
300                        public String[] symbol(){
301                                return new String[] {"<"};
302                        }
303                }  ,
304                le()  {
305                        /**
306                         * 与えられた左辺と右辺を元に演算子付きの文字列を作成する。
307                         * 第3引数のbooleanは、trueの時に値が数値であることを意味する。
308                         *
309                         * @param       left    左辺文字列
310                         * @param       right   右辺文字列
311                         * @param       is_num  数値かどうか(trueで、数値を指定)
312                         * @return      演算子を加えた結果
313                         * @og.rtnNotNull
314                         */
315                        public String apply(final String left , final String right, final boolean is_num) {
316                                if( is_num ) {
317                                        return leftVal(left) + "<=\t " + right;
318                                }else{
319                                        return leftVal(left) + "<=\t '" + right + "'";
320                                }
321                        }
322                        /**
323                         * 演算子(シンボル)の文字列配列を返します。
324                         *
325                         * @return      シンボル文字列配列
326                         * @og.rtnNotNull
327                         */
328                        public String[] symbol(){
329                                return new String[] {"<="};
330                        }
331                }  ,
332                not() {
333                        /**
334                         * 与えられた左辺と右辺を元に演算子付きの文字列を作成する。
335                         * 第3引数のbooleanは、trueの時に値が数値であることを意味する。
336                         *
337                         * @param       left    左辺文字列
338                         * @param       right   右辺文字列
339                         * @param       is_num  数値かどうか(trueで、数値を指定)
340                         * @return      演算子を加えた結果
341                         * @og.rtnNotNull
342                         */
343                        public String apply(final String left , final String right, final boolean is_num) {
344                                if( is_num ) {
345                                        return leftVal(left) + "!=\t " + right;
346                                } else {
347                                        return leftVal(left) + "!=\t '" + right + "'";
348                                }
349                        }
350                        /**
351                         * 演算子(シンボル)の文字列配列を返します。
352                         *
353                         * @return      シンボル文字列配列
354                         * @og.rtnNotNull
355                         */
356                        public String[] symbol(){
357                                return new String[] {"!="};
358                        }
359                } ,
360                bw()  {
361                        /**
362                         * 与えられた左辺と右辺を元に演算子付きの文字列を作成する。
363                         * 第3引数のbooleanは、trueの時に値が数値であることを意味する。
364                         *
365                         * @param       left    左辺文字列
366                         * @param       right   右辺文字列
367                         * @param       is_num  数値かどうか(trueで、数値を指定)
368                         * @return      演算子を加えた結果
369                         * @og.rtnNotNull
370                         */
371                        public String apply(final String left , final String right, final boolean is_num) {
372                                if( is_num ) {
373                                        return leftVal(left) + "between " + betweenFormat( right , "_FROM" ) + " and " + betweenFormat( right , "_TO" );
374                                }else {
375                                        return leftVal(left) + "between '" + betweenFormat( right , "_FROM" ) + "' and '" + betweenFormat( right , "_TO" ) + "'";
376                                }
377                        }
378                        /**
379                         * 演算子(シンボル)の文字列配列を返します。
380                         *
381                         * @return      シンボル文字列配列
382                         * @og.rtnNotNull
383                         */
384                        public String[] symbol(){
385                                return new String[] {"between"};
386                        }
387                } ,
388                in() {
389                        /**
390                         * 与えられた左辺と右辺を元に演算子付きの文字列を作成する。
391                         * 第3引数のbooleanは、trueの時に値が数値であることを意味する。
392                         *
393                         * @param       left    左辺文字列
394                         * @param       right   右辺文字列
395                         * @param       is_num  数値かどうか(trueで、数値を指定)
396                         * @return      演算子を加えた結果
397                         * @og.rtnNotNull
398                         */
399                        public String apply(final String left , final String right, final boolean is_num) {
400                                return leftVal(left) + "in\t (" +inFormat( right , is_num ) + ")";
401                        }
402                        /**
403                         * 演算子(シンボル)の文字列配列を返します。
404                         *
405                         * @return      シンボル文字列配列
406                         * @og.rtnNotNull
407                         */
408                        public String[] symbol(){
409                                return new String[] {"in"};
410                        }
411                };
412
413                // 6.3.9.1 (2015/11/27) 修飾子を、なし → private に変更。
414                private static final String[] TABS = { "\t\t\t\t" , "\t\t\t" , "\t\t" , "\t" };         // 5.6.4.4 (2013/05/31)
415
416                private static final Pattern LK1_PTN = Pattern.compile("like\\s+\\'\\{@(\\w*?)\\}%\\'");
417                private static final Pattern LK2_PTN = Pattern.compile("like\\s+\\'%\\{@(\\w*?)\\}\\'");
418                private static final Pattern LK3_PTN = Pattern.compile("like\\s+\\'%\\{@(\\w*?)\\}%\\'");
419
420                /**
421                 * 演算子の記号を略語に変換する。
422                 *
423                 * @og.rev 5.6.4.4 (2013/05/31) タブによる位置合わせの計算方法修正。
424                 *
425                 * @param left  引数
426                 * @return      演算子の記号の略語
427                 * @og.rtnNotNull
428                 */
429                private static String leftVal( final String left ) {
430                        final int adrs = (left.length()-1)/4 > 3 ? 3 : (left.length()-1)/4 ;
431                        return left + TABS[adrs] ;                                                                                              // 4タブを想定。
432                }
433
434                /**
435                 * 与えられた左辺と右辺を元に演算子付きの文字列を作成する。
436                 * 第3引数のbooleanは、trueの時に値が数値であることを意味する。
437                 *
438                 * @param       left    左辺文字列
439                 * @param       right   右辺文字列
440                 * @param       is_num  数値かどうか(trueで、数値を指定)
441                 * @return      演算子を加えた結果
442                 * @og.rtnNotNull
443                 */
444                public abstract String apply(final String left , final String right , final boolean is_num);
445
446                /**
447                 * 演算子を返却する。
448                 *
449                 * @return String[] 演算子
450                 */
451                public abstract String[] symbol();
452
453                /**
454                 * IN句の値を組み立てなおします。
455                 *
456                 * @og.rev 6.3.9.1 (2015/11/27) 修飾子 なし → private に変更。
457                 *
458                 * @param str String
459                 * @param is_number boolean
460                 * @return      IN句のフォーマット
461                 * @og.rtnNotNull
462                 */
463                private static String inFormat(final String str , final boolean is_number){
464                        final StringBuilder formated = new StringBuilder( BUFFER_MIDDLE );
465                        final String[] ins = str.split( "," );
466                        for( final String in :ins ){
467                                if( formated.length() > 0 ){
468                                        formated.append( ',' );                                 // 6.0.2.5 (2014/10/31) char を append する。
469                                }
470                                if( is_number ) {
471                                        formated.append( in );
472                                }else{
473                                        formated.append( '\'' ).append( in ).append( '\'' );
474                                }
475                        }
476
477                        return formated.toString();
478
479                }
480
481                /**
482                 * BETWEENを組み立てなおす。
483                 *
484                 * @og.rev 6.3.9.1 (2015/11/27) 修飾子 なし → private に変更。
485                 *
486                 * @param str String
487                 * @param suffix String
488                 * @return      BETWEENのフォーマット
489                 * @og.rtnNotNull
490                 */
491                private static String betweenFormat( final String str , final String suffix ){
492                        final StringBuilder sb = new StringBuilder( str );
493                        if( str.indexOf("{@") == 0 ){
494                                sb.insert( sb.length() - 1 , suffix );
495                        }else{
496                                sb.append( suffix );
497                        }
498                        return sb.toString();
499                }
500
501        //      /**
502        //       * 演算子の記号を略語に変換する。
503        //       *
504        //       * @og.rev 6.3.9.1 (2015/11/27) 修飾子 なし → private に変更。
505        //       * @og.rev 6.4.3.2 (2016/02/19) private に変更したところ、どこからも使われていないので、廃止します。
506        //       *
507        //       * @param arg   引数
508        //       * @return      演算子の記号の略語
509        //       * @og.rtnNotNull
510        //       */
511        //      private static String convert(final String arg){
512        //              for( final WHERE_OPERATORS fnc : values() ){
513        //                      if( fnc.symbol().length == 1 && arg.trim().indexOf( fnc.symbol()[0] ) == 0 ){
514        //                              return fnc.toString();
515        //                      }
516        //                      if( fnc.symbol().length == 3){
517        //                              Matcher matcher = LK1_PTN.matcher( arg );
518        //                              if( matcher.find() ){
519        //                                      return lk1.toString();
520        //                              }
521        //                              matcher = LK2_PTN.matcher( arg );
522        //                              if( matcher.find() ){
523        //                                      return lk2.toString();
524        //                              }
525        //                              matcher = LK3_PTN.matcher( arg );
526        //                              if( matcher.find() ){
527        //                                      return lk3.toString();
528        //                              }
529        //                      }
530        //              }
531        //              return "";
532        //      }
533        }
534}