    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.Matcher;
    019import java.util.regex.Pattern;
    020import java.util.Locale;
    021
    022/**
    023 * JSPの生成・データ取り込み処理で必要な列挙型をまとめたクラス。
    024 *
    025 * 主にキーワード管理とプログラム中のswitch文の削減を目的として作成。
    026 *
    027 *
    028 * @author Takeshi.Takada
    029 *
    030 */
    031public class JspEnumeration {
    032        /**
    033         * GROUP BY句を必要とする関数を列挙します。
    034         *
    035         * contains、searchと言った独自メソッドも実装しています。
    036         *
    037         */
    038//      protected static enum GROUPING_FUNCTIONS { MAX , MIN , SUM , COUNT , max , min , sum , count ;
    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( GROUPING_FUNCTIONS fnc : values() ){
    051//                              if ( arg.equals( fnc.toString() ) ){
    052                                if ( arg.equalsIgnoreCase( fnc.toString() ) ){
    053                                        return true;
    054                                }
    055                        }
    056                        return false;
    057                }
    058
    059                /**
    060                 * 自身に列挙されている値が与えられた文字列に含まれているか検証する。
    061                 * 含まれている場合は真を返す。
    062                 * 含まれていない場合は偽を返す。
    063                 *
    064                 * @param arg   引数
    065                 * @return      検証の結果
    066                 */
    067                public static boolean search( final String arg ) {
    068                        String argU = arg.toUpperCase(Locale.JAPAN);
    069
    070                        for( GROUPING_FUNCTIONS fnc : values() ){
    071//                              if( arg.indexOf( fnc.toString() ) > -1 ) {
    072                                if( argU.indexOf( fnc.toString() ) > -1 ) {
    073                                        return true;
    074                                }
    075                        }
    076                        return false;
    077                }
    078        }
    079
    080        /**
    081         * データ上はただの文字列として扱う関数を列挙します。
    082         * (注：現在、列挙中の関数はOracleの内容です。)
    083         *
    084         */
    085        public static enum TREATS_STRING_FUNCTIONS {
    086                CASE ,
    087                CEIL , ROUND , FLOOR , TRUNC , MOD , CHR , CONCAT , SUBSTR , INITCAP ,
    088                SUBSTRB , LOWER , TRIM , LPAD   , LTRIM , UPPER , REPLACE , USER , RPAD ,
    089                ASCII , LENGTH , LENGTHB , INSTR , POSITION , INSTRB  , ADD_MONTHS , DAYOFMONTH ,
    090                MONTHNAME , TIMESTAMPADD , CURDATE , DAYOFWEEK , MONTHS_BETWEEN  , TIMESTAMPDIFF ,
    091                CURRENT_DATE  , DAYOFYEAR , NEXT_DAY  , CURRENT_TIME  , HOUR , NOW , WEEK , CURRENT_TIMESTAMP  ,
    092                LAST_DAY  , YEAR , CURTIME , MINUTE , SECOND , DAYNAME , MONTH , SYSDATE  , CAST , AVG   ,
    093                CONVERT , DATABASE  , TO_CHAR  , DECODE , TO_NUMBER  , EXTRACT , TO_DATE  , GREATEST , STDDEV ,
    094                INTERVAL , VARIANCE , LEAST , LOCATE , NVL  ;
    095
    096                /**
    097                 * 関数の内容に第二引数の内容を付加する処理を実装します
    098                 * 第二引数の内容
    099                 * 0:カラムへ付与するテーブル名(テーブル別名)
    100                 *
    101                 * @param column String
    102                 * @param args String[]
    103                 * @return      関数を更新した結果
    104                 */
    105                public String update( final String column , final String[] args ) {
    106                        return column;
    107                }
    108
    109        }
    110
    111        /**
    112         * 演算子を列挙する。
    113         *
    114         * ●使用例
    115         * WHERE_OPERATORS op = WHERE_OPERATORS.valueOf("eq");
    116         * System.out.println(op.apply("GF92.CLM","{&#064;CLM}",false));
    117         *
    118         * ●上記処理結果
    119         * GF92.CLM     =       '{&#064;CLM}'
    120         *
    121         */
    122        public static enum WHERE_OPERATORS {
    123                eq() {
    124                        public String apply(final String left , final String right, final boolean is_num) {
    125                                if ( is_num ){
    126                                        return leftVal(left) + "=\t " + right ;
    127                                }else {
    128                                        return leftVal(left) + "=\t '" + right + "'";
    129                                }
    130                        }
    131                        public String[] symbol(){
    132                                return new String[] {"="};
    133                        }
    134                }  ,
    135                lk1() {
    136                        public String apply(final String left , final String right, final boolean is_num) {
    137                                return leftVal(left) + "like '" + right + "%'";
    138                        }
    139                        public String[] symbol(){
    140                                return new String[] {"like","","%"};
    141                        }
    142                }  ,
    143                lk2() {
    144                        public String apply(final String left , final String right, final boolean is_num) {
    145                                return leftVal(left) + "like '%" + right + "'";
    146                        }
    147                        public String[] symbol(){
    148                                return new String[] {"like","%",""};
    149                        }
    150                }  ,
    151                lk3() {
    152                        public String apply(final String left , final String right, final boolean is_num) {
    153                                return leftVal(left) + "like '%" + right + "%'";
    154                        }
    155                        public String[] symbol(){
    156                                return new String[] {"like","%","%"};
    157                        }
    158                }  ,
    159                gt() {
    160                        public String apply(final String left , final String right, final boolean is_num) {
    161                                if ( is_num ) {
    162                                        return leftVal(left) + ">\t " + right + "";
    163                                }else{
    164                                        return leftVal(left) + ">\t '" + right + "'";
    165                                }
    166                        }
    167                        public String[] symbol(){
    168                                return new String[] {">"};
    169                        }
    170                }  ,
    171                ge() {
    172                        public String apply(final String left , final String right, final boolean is_num) {
    173                                if ( is_num ) {
    174                                        return leftVal(left) + ">=\t " + right + "";
    175                                }else{
    176                                        return leftVal(left) + ">=\t '" + right + "'";
    177                                }
    178                        }
    179                        public String[] symbol(){
    180                                return new String[] {">="};
    181                        }
    182                }  ,
    183                lt()  {
    184                        public String apply(final String left , final String right, final boolean is_num) {
    185                                if ( is_num ) {
    186                                        return leftVal(left) + "<\t " + right + "";
    187                                }else {
    188                                        return leftVal(left) + "<\t '" + right + "'";
    189                                }
    190                        }
    191                        public String[] symbol(){
    192                                return new String[] {"<"};
    193                        }
    194                }  ,
    195                le()  {
    196                        public String apply(final String left , final String right, final boolean is_num) {
    197                                if ( is_num ){
    198                                        return leftVal(left) + "<=\t " + right + "";
    199                                }else{
    200                                        return leftVal(left) + "<=\t '" + right + "'";
    201                                }
    202                        }
    203                        public String[] symbol(){
    204                                return new String[] {"<="};
    205                        }
    206                }  ,
    207                not() {
    208                        public String apply(final String left , final String right, final boolean is_num) {
    209                                if ( is_num ) {
    210                                        return leftVal(left) + "!=\t " + right + "";
    211                                } else {
    212                                        return leftVal(left) + "!=\t '" + right + "'";
    213                                }
    214                        }
    215                        public String[] symbol(){
    216                                return new String[] {"!="};
    217                        }
    218                } ,
    219                bw()  {
    220                        public String apply(final String left , final String right, final boolean is_num) {
    221                                if ( is_num ) {
    222                                        return leftVal(left) + "between " + betweenFormat( right , "_FROM" ) + " and " + betweenFormat( right , "_TO" ) + "";
    223                                }else {
    224                                        return leftVal(left) + "between '" + betweenFormat( right , "_FROM" ) + "' and '" + betweenFormat( right , "_TO" ) + "'";
    225                                }
    226                        }
    227                        public String[] symbol(){
    228                                return new String[] {"between"};
    229                        }
    230                } ,
    231                in() {
    232                        public String apply(final String left , final String right, final boolean is_num) {
    233                                return leftVal(left) + "in\t (" +inFormat( right , is_num ) + ")";
    234                        }
    235                        public String[] symbol(){
    236                                return new String[] {"in"};
    237                        }
    238                } ,
    239                ;
    240
    241//              static final String[] TABS = new String[] { "\t\t\t" , "\t\t" , "\t" };
    242                static final String[] TABS = new String[] { "\t\t\t\t" , "\t\t\t" , "\t\t" , "\t" };            // 5.6.4.4 (2013/05/31)
    243
    244                /**
    245                 * 演算子の記号を略語に変換する。
    246                 *
    247                 * @og.rev 5.6.4.4 (2013/05/31) タブによる位置合わせの計算方法修正。
    248                 *
    249                 * @param left  引数
    250                 * @return      演算子の記号の略語
    251                 */
    252                static String leftVal( final String left ) {
    253//                      return left + TABS[Math.max( left.length()/4, TABS.length-1 )] ;                // ４タブを想定。
    254
    255                        int adrs = ((left.length()-1)/4 > 3 ) ? 3 : (left.length()-1)/4 ;
    256                        return left + TABS[adrs] ;                                                                                              // ４タブを想定。
    257                }
    258
    259                /**
    260                 * 与えられた左辺と右辺を元に演算子付きの文字列を作成する。
    261                 * 第３引数のbooleanは、trueの時に値が数値であることを意味する。
    262                 *
    263                 * @param left String
    264                 * @param right String
    265                 * @param is_num boolean
    266                 * @return      演算子を加えた結果
    267                 */
    268                abstract public String apply(final String left , final String right , final boolean is_num);
    269
    270                /**
    271                 * 演算子を返却する。
    272                 *
    273                 * @return String[] 演算子
    274                 */
    275                abstract public String[] symbol();
    276
    277                /**
    278                 * IN句の値を組み立てなおします。
    279                 *
    280                 * @param str String
    281                 * @param is_number boolean
    282                 * @return      IN句のフォーマット
    283                 */
    284                static String inFormat(final String str , final boolean is_number){
    285                        StringBuilder formated = new StringBuilder("");
    286                        String[] ins = str.split( "," );
    287                        for (String in :ins ){
    288                                if (formated.length() > 0 ){
    289                                        formated.append( "," );
    290                                }
    291                                if ( is_number ) {
    292                                        formated.append( in );
    293                                }else{
    294                                        formated.append( "'" ).append( in ).append( "'" );
    295                                }
    296                        }
    297
    298                        return formated.toString();
    299
    300                }
    301
    302                /**
    303                 * BETWEENを組み立てなおす。
    304                 *
    305                 * @param str String
    306                 * @param suffix String
    307                 * @return      BETWEENのフォーマット
    308                 */
    309                static String betweenFormat(final String str , final String suffix){
    310                        StringBuilder sb = new StringBuilder(str);
    311                        if ( str.indexOf("{@") == 0 ){
    312                                sb.insert( sb.length() - 1 , suffix );
    313                        }else{
    314                                sb.append( suffix );
    315                        }
    316                        return sb.toString();
    317                }
    318
    319                static Pattern LK1_PTN = Pattern.compile("like\\s+\\'\\{@(\\w*?)\\}%\\'");
    320                static Pattern LK2_PTN = Pattern.compile("like\\s+\\'%\\{@(\\w*?)\\}\\'");
    321                static Pattern LK3_PTN = Pattern.compile("like\\s+\\'%\\{@(\\w*?)\\}%\\'");
    322
    323                /**
    324                 * 演算子の記号を略語に変換する。
    325                 *
    326                 * @param arg   引数
    327                 * @return      演算子の記号の略語
    328                 */
    329                static String convert(final String arg){
    330                        for( WHERE_OPERATORS fnc : values() ){
    331                                if ( fnc.symbol().length == 1 && arg.trim().indexOf( fnc.symbol()[0] ) == 0 ){
    332                                        return fnc.toString();
    333                                }
    334                                if( fnc.symbol().length == 3){
    335//                                      Matcher matcher = Pattern.compile("like\\s+\\'\\{@(\\w*?)\\}%\\'").matcher( arg );
    336                                        Matcher matcher = LK1_PTN.matcher( arg );
    337                                        if (matcher.find()){
    338                                                return lk1.toString();
    339                                        }
    340//                                      matcher = Pattern.compile("like\\s+\\'%\\{@(\\w*?)\\}\\'").matcher( arg );
    341                                        matcher = LK2_PTN.matcher( arg );
    342                                        if (matcher.find()){
    343                                                return lk2.toString();
    344                                        }
    345//                                      matcher = Pattern.compile("like\\s+\\'%\\{@(\\w*?)\\}%\\'").matcher( arg );
    346                                        matcher = LK3_PTN.matcher( arg );
    347                                        if (matcher.find()){
    348                                                return lk3.toString();
    349                                        }
    350                                }
    351                        }
    352                        return "";
    353                }
    354        }
    355
    356}