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 */ 016 package org.opengion.plugin.develop; 017 018 import java.util.ArrayList; 019 import java.util.List; 020 import java.util.Map; 021 import java.util.HashMap; 022 import java.util.regex.Matcher; 023 import java.util.regex.Pattern; 024 025 import org.opengion.hayabusa.develop.AbstractJspCreate; 026 import org.opengion.hayabusa.develop.JspEnumeration.GROUPING_FUNCTIONS ; 027 import org.opengion.hayabusa.develop.JspEnumeration.WHERE_OPERATORS ; 028 import org.opengion.hayabusa.develop.JspConvertEntity; 029 import org.opengion.fukurou.xml.OGElement; 030 import static org.opengion.fukurou.util.StringUtil.isNull; 031 032 /** 033 * result.jspの<og:query >タグを作?します? 034 * 035 * ●使用? 036 * <og:query 037 * command = "{@command}" 038 * debug = "{@debug} 039 * dbid = "{@FROM_DBID}" 040 * maxRowCount = "{@maxRowCount}" > 041 * select A1.xx , A1.xx ,・・・ 042 * from xxx A1 inner join xxx B1 043 * where ・・・ 044 * group by ・・・ 045 * having ・・・ 046 * ORDER BY ・・・ 047 * </og:query> 048 * 049 * @og.rev 5.6.1.2 (2013/02/22) ??連結から?XML処?るよ?変更します? 050 * @author Takeshi.Takada 051 * 052 */ 053 public class JspCreate_QUERY extends AbstractJspCreate { 054 //* こ?プログラ??VERSION??を設定します? {@value} */ 055 private static final String VERSION = "5.6.4.4 (2013/05/31)" ; 056 057 private List<JspConvertEntity> QUERY_ROWS ; 058 private List<JspConvertEntity> RESULT_ROWS ; 059 private List<JspConvertEntity> CONST_ROWS ; 060 private List<JspConvertEntity> JOIN_ROWS ; 061 private List<JspConvertEntity> JOIN_ON_ROWS ; 062 private List<JspConvertEntity> HAVING_ROWS ; 063 064 private String ns = ""; // 5.2.1.0 (2010/10/01) 名前空? 065 066 /** 067 * 初期化メソ? 068 * 069 * ?で使用する JspConvertEntity の リス?のマップを受け取り、?期化を行います? 070 * 071 * @og.rev 5.2.1.0 (2010/10/01) 名前空間を、og 決め打ちから、名前空間指定無しに変更します? 072 * 073 * @param master JspConvertEntityのリスト?マッ? 074 */ 075 @Override 076 protected void init( final Map<String,List<JspConvertEntity>> master ) { 077 QUERY_ROWS = master.get( "QUERY" ); 078 RESULT_ROWS = master.get( "RESULT" ); 079 CONST_ROWS = master.get( "CONST" ); 080 JOIN_ROWS = master.get( "JOIN" ); 081 JOIN_ON_ROWS= master.get( "JOIN_ON" ); 082 HAVING_ROWS = master.get( "HAVING" ); 083 084 // KEY = "og:query"; 085 KEY = ":query"; // 5.2.1.0 (2010/10/01) 名前空間指定無? 086 NAME = "result"; 087 } 088 089 /** 090 * JSPに出力するタグの?を作?します? 091 * 引数より作?前?タグの属??を確認するする事が出来ます? 092 * 093 * @og.rev 5.2.1.0 (2010/10/01) メソ?の引数を?OGAttributes から OGElement に変更します? 094 * @og.rev 5.2.1.0 (2010/10/01) 名前空間を、og 決め打ちから、引数を使用するように変更します? 095 * @og.rev 5.6.4.4 (2013/05/31) select カラ?、コメントを付与します? 096 * 097 * @param ele OGElementエレメントオブジェク? 098 * @param nameSpace こ?ドキュメント?nameSpace( og と?mis と?) 099 * 100 * @return 変換された文字? 101 * @throws Throwable 変換時?エラー 102 */ 103 @Override 104 protected String execute( final OGElement ele , final String nameSpace ) throws Throwable { 105 ns = (nameSpace.length() == 0) ? "" : nameSpace + ":" ; // 5.2.1.0 (2010/10/01) 名前空? 106 107 // こ? OGElement の階層の深さを探ります? 108 // ele.getText( para ) とすることでXML全体を階層表示できる? 109 // int para = ele.getParentCount(); 110 111 // TODO Auto-generated method stub 112 //書き?す文字?を作?開始? 113 StringBuilder tag = new StringBuilder(); 114 115 List<String> selects = new ArrayList<String>(); 116 List<String> clmCmnt = new ArrayList<String>(); // 5.6.4.4 (2013/05/31) select カラ?、コメントを付与します? 117 List<String> tables = new ArrayList<String>(); 118 List<String> orders = new ArrayList<String>(); 119 List<String> group = new ArrayList<String>(); 120 List<String> having_part = new ArrayList<String>(); 121 List<String> having_grouping_column = new ArrayList<String>(); 122 123 //HAVING??から<og:query>タグの?スト部を生成する準備をします? 124 // if ( HAVING_ROWS != null && HAVING_ROWS.size() > 0 ){ 125 if ( isNotEmpty(HAVING_ROWS) ){ 126 for( JspConvertEntity row : HAVING_ROWS ){ 127 having_part.add(row.getRemarks()); 128 if( GROUPING_FUNCTIONS.search( row.getRemarks() ) ){ 129 having_grouping_column.add( row.getFullColumnName() ); 130 } 131 } 132 } 133 //RESULT??から<og:query>タグの?スト部を生成する準備をします? 134 boolean grouping = false; 135 // if( RESULT_ROWS != null ) { 136 if ( isNotEmpty(RESULT_ROWS) ){ 137 for(int i = 0 ; i < RESULT_ROWS.size() ; i++){ 138 JspConvertEntity result = RESULT_ROWS.get(i); 139 //Select句の??を作? 140 selects.add( result.getSelectPartColumnName() ); 141 // 5.6.4.4 (2013/05/31) select カラ?、コメントを付与します? 142 clmCmnt.add( result.getTableName() + "." + result.getColumnCommentName() ); 143 //??ブル名を検証して、テーブル数のみの??にします? 144 if( tables != null && !tables.contains( result.getTableName() ) ) { 145 tables.add( result.getFromPartTableName() ); 146 } 147 //並び?利用するカラ?取得する? 148 if ("1".equals( result.getUseOrder() )) { 149 orders.add(Integer.toString( i + 1 )); 150 } 151 //GROUP BYに?な??を取得します? 152 if( GROUPING_FUNCTIONS.contains( result.getRemarks() ) ){ 153 grouping = true; 154 // }else if(having_grouping_column.indexOf( result.getFullColumnName() ) > -1 ){ 155 // group.add( result.getFullColumnName() ); 156 }else{ 157 group.add( result.getFullColumnName() ); 158 } 159 } 160 } 161 162 //JOIN??から<og:query>タグの?スト部(join句)を生成する準備をします? 163 JspConvertEntity join_on = null; 164 // if (JOIN_ON_ROWS != null && JOIN_ON_ROWS.size() > 0 ) { 165 if ( isNotEmpty(JOIN_ON_ROWS) ){ 166 join_on = JOIN_ON_ROWS.get( 0 ); 167 } 168 //JOIN??から<og:query><og:where><og:and>タグの検索句を生成する準備をします? 169 // if( QUERY_ROWS != null && CONST_ROWS != null && CONST_ROWS.size() > 0 ) { 170 if ( QUERY_ROWS != null && isNotEmpty(CONST_ROWS) ){ 171 QUERY_ROWS.addAll( CONST_ROWS ); 172 } 173 174 // tag.append("<og:query command=\"{@command}\" debug=\"{@debug}\" dbid=\"{@FROM_DBID}\" maxRowCount=\"{@maxRowCount}\">").append( CR ); 175 // tag.append("<" ).append( ns ).append( "query command=\"{@command}\" debug=\"{@debug}\" dbid=\"{@FROM_DBID}\" maxRowCount=\"{@maxRowCount}\">").append( CR ); 176 177 OGElement queryEle = new OGElement( ns + "query" ); 178 queryEle.addAttr( "command" ,"{@command}" ); 179 queryEle.addAttr( "debug" ,"{@debug}" ); 180 queryEle.addAttr( "dbid" ,"{@FROM_DBID}" ); 181 queryEle.addAttr( "maxRowCount" ,"{@maxRowCount}" ); 182 183 // tag.append( queryText(selects , tables , JOIN_ROWS , join_on ) ); 184 185 // queryEle.addNode( queryText(selects , tables , JOIN_ROWS , join_on ) ); 186 queryEle.addNode( queryText(selects , clmCmnt , tables , JOIN_ROWS , join_on ) ); // 5.6.4.4 (2013/05/31) select カラ?、コメントを付? 187 188 // tag.append( CR ); 189 // if ( QUERY_ROWS != null && QUERY_ROWS.size() > 0 ){ 190 if ( isNotEmpty(QUERY_ROWS) ){ 191 // tag.append("\t<og:where>").append( CR ); 192 // tag.append("\t<").append( ns ).append("where>").append( CR ); 193 194 OGElement whereEle = new OGElement( ns + "where" ); 195 196 for ( JspConvertEntity where : QUERY_ROWS ) { 197 if ("QUERY".equals(where.getType())){ 198 // tag.append(andWhereQuery(where.getFullColumnName() , where.getRemarks() ,"{@"+ where.getColumnName() +"}" ,where.isNumber())); 199 whereEle.addNode( andWhereQuery(where.getFullColumnName() , where.getRemarks() ,"{@"+ where.getColumnName() +"}" ,where.isNumber()) ); 200 } 201 if ("CONST".equals(where.getType())) { 202 // tag.append(andWhereConst( where.getFullColumnName(), where.getRemarks() , where.isNumber())); 203 whereEle.addNode( andWhereConst( where.getFullColumnName(), where.getRemarks() , where.isNumber()) ); 204 } 205 } 206 // tag.append("\t</og:where>").append( CR ); 207 // tag.append("\t</").append( ns ).append( "where>").append( CR ); 208 queryEle.addNode( whereEle ); 209 } 210 // if ( grouping == true || having_grouping_column.size() > 0 ) { 211 // if ( grouping || having_grouping_column.size() > 0 ) { 212 if ( grouping || !having_grouping_column.isEmpty() ) { 213 // tag.append( "\t\tgroup by " ).append(chainChar(group,",")).append( CR ); 214 // queryEle.addNode( "\t\tgroup by " + chainChar(group,",") + CR ); 215 queryEle.addNode( T2 + "group by " + chainChar(group,",") + CR ); 216 } 217 // if ( having_grouping_column.size() > 0 ){ 218 if ( !having_grouping_column.isEmpty() ){ 219 // tag.append( "\t\thaving " ).append(chainChar(having_part ," and ")).append( CR ); 220 // queryEle.addNode( "\t\thaving " + chainChar(having_part ," and ") + CR ); 221 queryEle.addNode( T2 + "having " + chainChar(having_part ," and ") + CR ); 222 } 223 // if ( orders.size() > 0 ){ 224 if ( !orders.isEmpty() ){ 225 // tag.append( apperText("ORDER BY" , "ORDER_BY" , orders ) ); 226 queryEle.addNode( apperEle( "ORDER BY" , "ORDER_BY" , orders ) ); 227 } 228 // tag.append( CR ); 229 // tag.append("</og:query>").append( CR ); 230 // tag.append("</").append( ns ).append( "query>").append( CR ); 231 232 // return tag.toString(); 233 return queryEle.getText(0); 234 } 235 236 private static final String SPACE = " " ; // カラ??位置合わせ用 237 238 /** 239 * result.jspのog:queryタグの?スト部を生成します? 240 * 241 * 補足?? 242 * 引数のjoin_onがnullでな?き?、優先的にjoin_onの?でJOIN句を生成します? 243 * 244 * @og.rev 5.6.4.4 (2013/05/31) select カラ?、コメントを付与します? 245 * 246 * @param selects 検索SQLのリス? 247 * @param clmCmnt カラ?メント?リス? 248 * @param tables ??ブル名?リス? 249 * @param joins JspConvertEntityのリス? 250 * @param join_on JspConvertEntityオブジェク? 251 * 252 * @return og:queryタグの?スト部 253 */ 254 // protected String queryText( final List<String> selects , final List<String> tables , 255 // final List<JspConvertEntity> joins ,final JspConvertEntity join_on ) { 256 protected String queryText( final List<String> selects , final List<String> clmCmnt , final List<String> tables , 257 final List<JspConvertEntity> joins ,final JspConvertEntity join_on ) { 258 StringBuilder sb = new StringBuilder(); 259 // sb.append( CR ).append( "\t\tselect" ).append( CR ); 260 sb.append( CR ).append( T2 ).append( "select" ).append( CR ); 261 // sb.append( "\t\t\t" ); 262 // sb.append( T3 ); 263 // sb.append( chainChar( selects , "," ) ); // 5.6.4.4 (2013/05/31) 以前?、カラ?カンマで単純につなげて??? 264 // 5.6.4.4 (2013/05/31) select カラ?、コメントを付与します? 265 int size = selects.size(); 266 for( int i=0; i<size; i++ ) { 267 sb.append( T3 ); 268 if( i == 0 ) { sb.append( " " ); } 269 else { sb.append( "," ); } 270 String clm = selects.get(i) ; 271 sb.append( clm ).append( SPACE.substring( clm.length() ) ).append( T3 ).append( T3 ).append( T3 ).append( T3 ); 272 sb.append( "<!-- " ).append( clmCmnt.get(i) ).append( " -->" ).append( CR ); 273 } 274 275 // sb.append( CR ); 276 // sb.append( "\t\tfrom " ); 277 sb.append( T2 ).append( "from " ); 278 279 if ( join_on != null ) { 280 //JOIN_ONが存在する場合?、直接SQLを?立てて処?終?る? 281 // sb.append( "\t\t" ); 282 sb.append( T2 ); 283 sb.append( join_on.getRemarks() ); 284 return sb.toString(); 285 } 286 287 // if( joins == null || joins.isEmpty() ) { 288 if( !isNotEmpty( joins ) ) { 289 sb.append( tables.get(0) ); 290 return sb.toString(); 291 } 292 293 //??ブルの?を構?化します? 294 TableStruct structs = createStruct(joins); 295 296 String before_left = ""; 297 String before_right = ""; 298 StringBuilder sbPre = new StringBuilder(""); 299 300 Map<String,String> mapJoinParts = new HashMap<String,String>(); 301 302 boolean isStartJoin = false; 303 304 for(int i = 0 ; i < joins.size() ; i++){ 305 //join句を作るのとネスト構?を作るのは処??させる? 306 JspConvertEntity join = joins.get( i ); 307 308 if(before_left.equals(join.getFromPartTableName())){ 309 //前?処?左側の??ブルは同じ 310 // if( before_right.equals(join.getJoinColumn().getFromPartTableName()) == false ) { 311 if( ! before_right.equals(join.getJoinColumn().getFromPartTableName()) ) { 312 //前?処?右側の??ブルが違? 313 sbPre.append( sqlJoinOn( "", join.getJoinColumn().getFromPartTableName() , join.getJoinType()) ); 314 isStartJoin = true; 315 } 316 }else { 317 //前?処?左側の??ブルが違? 318 // if( before_right.equals(join.getJoinColumn().getFromPartTableName()) == false ) { 319 if( ! before_right.equals(join.getJoinColumn().getFromPartTableName()) ) { 320 //前?処?右側の??ブルが違? 321 //前?処??Join句をテーブル名別にセ? 322 String str = sbPre.toString(); 323 mapJoinParts.put( before_left, str ); 324 //バッファを?期化 325 sbPre = new StringBuilder(); 326 sbPre.append( sqlJoinOn( join.getFromPartTableName() , join.getJoinColumn().getFromPartTableName() , join.getJoinType()) ); 327 isStartJoin = true; 328 } 329 } 330 // if ( isStartJoin == false ) { 331 if ( !isStartJoin ) { 332 // sbPre.append( " and").append( CR ); 333 // sbPre.append( CR ).append( "\t\t\tand\t"); 334 sbPre.append( CR ).append( T3 ).append( "and").append( T1 ); 335 } 336 // sbPre.append( "\t\t\t" ); 337 sbPre.append( join.getFullColumnName() ); 338 // sbPre.append( "\t\t=\t" ); 339 sbPre.append( T2 ).append( "=" ).append( T1 ); 340 sbPre.append( join.getJoinColumn().getFullColumnName() ); 341 before_left = join.getFromPartTableName(); 342 before_right = join.getJoinColumn().getFromPartTableName(); 343 isStartJoin = false; 344 } 345 //?? 346 mapJoinParts.put( before_left, sbPre.toString() ); 347 348 StringBuilder sbJoin = new StringBuilder(); 349 //Join句を?立てます? 350 // sb.append( createJoinPart(structs.getJoinTables(),mapJoinParts,sbJoin).toString() ); 351 createJoinPart(structs.getJoinTables(),mapJoinParts,sbJoin); 352 sb.append( sbJoin.toString() ); 353 354 return sb.toString(); 355 } 356 357 /** 358 * join句の?を作?する? 359 * 360 * @param left join句のレフト 361 * @param right join句のライ? 362 * @param join_type [1:inner join/そ??left outer join] 363 * 364 * @return join句の? 365 */ 366 private String sqlJoinOn(final String left , final String right ,final String join_type){ 367 StringBuilder sb = new StringBuilder(); 368 // sb.append( " " ).append( CR ); 369 sb.append( " " ); 370 sb.append( left ); 371 if("1".equals( join_type )){ 372 sb.append( " inner join " ); 373 }else{ 374 sb.append( " left outer join " ); 375 } 376 sb.append( right ); 377 // sb.append( " on" ).append( CR ); 378 // sb.append( CR ).append( "\t\t\ton\t" ); 379 sb.append( CR ).append( T3 ).append( "on" ).append( T1 ); 380 return sb.toString(); 381 } 382 383 /** 384 * JOIN句を?立てます? 385 * 386 * JOIN句は、?部で再帰処?れます?引数の StringBuilder に?的な JOIN句が?納されます? 387 * 388 * @param structs ??ブル?の構?化TableStructのリス? 389 * @param join JOIN句マッ? 390 * @param buff StringBuilderオブジェク? 391 */ 392 private void createJoinPart( final List<TableStruct> structs , final Map<String,String> join ,final StringBuilder buff ) { 393 Matcher matcher = null; 394 for(int i = 0 ; i < structs.size() ; i++){ 395 TableStruct struct = structs.get(i); 396 String part = join.get(struct.getTableName()); 397 if ( part != null ){ 398 // matcher = Pattern.compile( "join " + struct.getTableName() + " on").matcher( buff ); 399 matcher = Pattern.compile( "join " + struct.getTableName() ).matcher( buff ); 400 if( matcher.find()) { 401 int start = matcher.start(); 402 buff.delete(start,matcher.end()); 403 // buff.insert(start , "join ( " + part + " ) on"); 404 buff.insert(start , "join ( " + part + " )" ); 405 }else{ 406 buff.append( part ); 407 } 408 } 409 createJoinPart(struct.getJoinTables(),join,buff); 410 } 411 } 412 413 /** 414 * result.jspの og:query og:appear タグを生成します? 415 * 416 * @og.rev 5.2.1.0 (2010/10/01) 名前空間を、og 決め打ちから、引数を使用するように変更します? 417 * 418 * @param start_key 開始キー 419 * @param value 値 420 * @param default_value 初期値リス? 421 * 422 * @return og:query og:appear タグ 423 */ 424 // protected String apperText( final String start_key , final String value , final List<String> default_value ){ 425 protected OGElement apperEle( final String start_key , final String value , final List<String> default_value ){ 426 // StringBuilder sb = new StringBuilder(); 427 // sb.append( "\t<").append( ns ).append( "appear startKey = \"" ); 428 // sb.append( start_key ); 429 // sb.append( "\" value = \"{@" ); 430 // sb.append( value ); 431 // sb.append( "}\"" ).append( CR ); 432 // sb.append( "\t\t\tdefaultVal = \"" ); 433 // sb.append( chainChar( default_value , "," ) ); 434 // sb.append( "\" />" ).append( CR ); 435 // return sb.toString(); 436 437 OGElement apper = new OGElement( ns + "appear" ); 438 apper.addAttr( "startKey" ,start_key ); 439 apper.addAttr( "value" ,"{@" + value + "}" ); 440 apper.addAttr( "defaultVal" ,chainChar( default_value , "," ) ); 441 return apper; 442 } 443 444 /** 445 * result.jspの og:query og:where og:and タグを生成します? 446 * 処?ループ:QUERY 447 * 448 * @param left 左側? 449 * @param operator オペレーター 450 * @param right 右側? 451 * @param is_number 数字かど?[true/false] 452 * 453 * @return og:and タグ 454 */ 455 // protected String andWhereQuery( final String left , final String operator , final String right , final boolean is_number){ 456 protected OGElement andWhereQuery( final String left , final String operator , final String right , final boolean is_number){ 457 // StringBuilder sb = new StringBuilder(); 458 // if ( operator == null || operator.trim().length() == 0 ){ 459 // if ( operator == null || operator.trim().isEmpty() ){ 460 // operator = "eq"; 461 // } 462 463 String ope = isNull(operator) ? "eq" : operator ; 464 465 WHERE_OPERATORS wrOpe = WHERE_OPERATORS.valueOf( ope ); 466 // sb.append( "\t\t<og:and value = \"" ).append( wrOpe.apply( left , right , is_number )).append( "\"\t/>" ).append( CR ); 467 // sb.append( "\t\t<").append( ns ).append( "and value = \"" ).append( wrOpe.apply( left , right , is_number )).append( "\"\t/>" ).append( CR ); 468 // return sb.toString(); 469 470 OGElement and = new OGElement( ns + "and" ); 471 and.addAttr( "value" , wrOpe.apply( left , right , is_number ) ); 472 return and; 473 } 474 475 /** 476 * result.jspのog:query og:where og:and タグを生成します? 477 * 処?ループ:CONST 478 * 479 * @param left 左側? 480 * @param right 右側? 481 * @param is_number 数字かど?[true/false] 482 * 483 * @return og:and タグ 484 */ 485 // protected String andWhereConst( final String left , final String right , final boolean is_number ){ 486 protected OGElement andWhereConst( final String left , final String right , final boolean is_number ){ 487 // String operator = ""; 488 // if ( right.indexOf( "," ) >= 0 ) { 489 // operator = "in"; 490 // }else{ 491 // operator = "eq"; 492 // } 493 String operator = ( right.indexOf( ',' ) >= 0 ) ? "in" : "eq"; 494 return andWhereQuery( left , operator , right , is_number ); 495 } 496 497 /** 498 * query.jspの og:column タグを生成します? 499 * 500 * @param name タグのname 501 * @param default_value 初期値 502 * 503 * @return og:columnタグ 504 */ 505 // protected String columnText( final String name , final String default_value ){ 506 // StringBuilder sb = new StringBuilder(); 507 // // sb.append( "\t<og:column name=\"" ); 508 // sb.append( "\t<").append( ns ).append( "column name=\"" ); 509 // sb.append( name ); 510 // sb.append( "\"" ); 511 // if ( default_value != null ) { 512 // sb.append( " defaultVal=\"" ); 513 // sb.append( default_value ); 514 // sb.append( "\" " ); 515 // } 516 // sb.append("/>"); 517 // return sb.toString(); 518 // } 519 520 /** 521 * ??ブルの結合関係を再現する構?体につめ直すメソ? 522 * 523 * @param joins JspConvertEntityのリス? 524 * 525 * @return ??ブルの結合関係を再現する構?? 526 */ 527 private TableStruct createStruct( final List<JspConvertEntity> joins ) { 528 TableStruct st = new TableStruct(); 529 for(int i = 0 ; i < joins.size() ; i++){ 530 JspConvertEntity join = joins.get( i ); 531 String left_name = join.getFromPartTableName(); 532 String right_name = join.getJoinColumn().getFromPartTableName(); 533 534 TableStruct left = st.getJoinTable( left_name ); 535 TableStruct right = st.getJoinTable( right_name ); 536 537 if (left == null && right == null) { 538 //全く?新規? 539 left = new TableStruct(); 540 left.setTableName( left_name ); 541 right = new TableStruct(); 542 right.setTableName(right_name); 543 left.addJoinTable( right ); 544 st.addJoinTable( left ); 545 }else{ 546 if( left != null && right == null ){ 547 right = new TableStruct(); 548 right.setTableName(right_name); 549 left.addJoinTable( right ); 550 } 551 } 552 } 553 return st; 554 } 555 556 /** 557 * ??ブルの結合状態を階層構図にする為のオブジェク? 558 * 559 * @author Administrator 560 * 561 */ 562 private static class TableStruct { 563 564 private final List<TableStruct> _joins = new ArrayList<TableStruct>(); 565 private String _table_name; 566 567 /** 568 * ??ブル名を設? 569 * 570 * @param table_name String 571 */ 572 public void setTableName( final String table_name ) { 573 _table_name = table_name; 574 } 575 576 /** 577 * ??ブル名を取? 578 * 579 * @return ??ブル? 580 */ 581 public String getTableName() { 582 return _table_name; 583 } 584 585 /** 586 * 結合??ブルを追? 587 * 588 * @param join_table String 589 */ 590 public void addJoinTable( final TableStruct join_table ) { 591 _joins.add(join_table); 592 } 593 594 /** 595 * 結合??ブルを?て取? 596 * 597 * @return 全ての結合??ブル 598 */ 599 public List<TableStruct> getJoinTables() { 600 return _joins; 601 } 602 603 /** 604 * ?したテーブルを取? 605 * 606 * @param table_name String 607 * @return ?したテーブル 608 */ 609 public TableStruct getJoinTable( final String table_name ) { 610 return search(_joins,table_name); 611 } 612 613 /** 614 * ??ブル同士が??して?か検証する? 615 * 616 * @param table_name String 617 * @return 検証した結果の真偽 618 */ 619 public boolean equalTable( final String table_name ) { 620 return (_table_name != null && _table_name.equals( table_name )) ; 621 // if(_table_name != null && _table_name.equals( table_name )) { 622 // return true; 623 // }else{ 624 // return false; 625 // } 626 } 627 628 /** 629 * ?したテーブルが存在して?か検証する? 630 * 631 * @param table_name String 632 * @return 検証した結果の真偽 633 */ 634 public boolean constains( final String table_name ) { 635 for(int i = 0; i < _joins.size() ; i++){ 636 TableStruct join = _joins.get( i ); 637 // if(join.equals(table_name)){ 638 if(join.equalTable(table_name)){ 639 return true; 640 } 641 } 642 return false; 643 } 644 645 /** 646 * 結合先を含めて?したテーブルを取得する? 647 * 648 * @param joins List<TableStruct> 649 * @param table_name String 650 * @return ?したテーブル 651 */ 652 private TableStruct search( final List<TableStruct> joins , final String table_name ) { 653 TableStruct join = null; 654 for(int i = 0; i < joins.size() ; i++){ 655 join = joins.get( i ); 656 // if(join.equals(table_name)){ 657 if(join.equalTable(table_name)){ 658 return join; 659 }else{ 660 join = search(join.getJoinTables(),table_name); 661 } 662 } 663 return join; 664 } 665 } 666 }