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