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    }