    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.plugin.develop;
    017
    018import java.util.ArrayList;
    019import java.util.List;
    020import java.util.Map;
    021import java.util.HashMap;
    022import java.util.regex.Matcher;
    023import java.util.regex.Pattern;
    024
    025import org.opengion.hayabusa.develop.AbstractJspCreate;
    026import org.opengion.hayabusa.develop.JspEnumeration.GROUPING_FUNCTIONS ;
    027import org.opengion.hayabusa.develop.JspEnumeration.WHERE_OPERATORS ;
    028import org.opengion.hayabusa.develop.JspConvertEntity;
    029import org.opengion.fukurou.xml.OGElement;
    030import static org.opengion.fukurou.util.StringUtil.isNull;
    031
    032/**
    033 * result.jspの&lt;og:query &gt;タグを作成します。
    034 *
    035 * ●使用例
    036 *      &lt;og:query
    037 *              command     = "{&#064;command}"
    038 *              debug       = "{&#064;debug}
    039 *              dbid        = "{&#064;FROM_DBID}"
    040 *              maxRowCount = "{&#064;maxRowCount}" &gt;
    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 *      &lt;/og:query&gt;
    048 *
    049 * @og.rev 5.6.1.2 (2013/02/22) 文字列連結から、XML処理するように変更します。
    050 * @author Takeshi.Takada
    051 *
    052 */
    053public 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}