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","{@CLM}",false)); 117 * 118 * ●上記処理結果 119 * GF92.CLM = '{@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 )] ; // 4タブを想定。 254 255 int adrs = ((left.length()-1)/4 > 3 ) ? 3 : (left.length()-1)/4 ; 256 return left + TABS[adrs] ; // 4タブを想定。 257 } 258 259 /** 260 * 与えられた左辺と右辺を元に演算子付きの文字列を作成する。 261 * 第3引数の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}