    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","{&#064;CLM}",false));
    114         *
    115         * ●上記処理結果
    116         * GF92.CLM     =       '{&#064;CLM}'
    117         *
    118         */
    119        public static enum WHERE_OPERATORS {
    120                eq() {
    121                        /**
    122                         * 与えられた左辺と右辺を元に演算子付きの文字列を作成する。
    123                         * 第３引数の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                         * 第３引数の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                         * 第３引数の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                         * 第３引数の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                         * 第３引数の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                         * 第３引数の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                         * 第３引数の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                         * 第３引数の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                         * 第３引数の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                         * 第３引数の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                         * 第３引数の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] ;                                                                                              // ４タブを想定。
    432                }
    433
    434                /**
    435                 * 与えられた左辺と右辺を元に演算子付きの文字列を作成する。
    436                 * 第３引数の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}