    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.view;
    017
    018import java.util.List;
    019
    020import org.opengion.fukurou.util.StringUtil;
    021import org.opengion.fukurou.util.TagBuffer;
    022import org.opengion.fukurou.util.XHTMLTag;
    023import org.opengion.hayabusa.common.HybsSystem;
    024import org.opengion.hayabusa.common.HybsSystemException;
    025import org.opengion.hayabusa.html.FormatterType;
    026import org.opengion.hayabusa.html.TableFormatter;
    027import org.opengion.hayabusa.html.ViewAjaxTreeTableParam;
    028
    029/**
    030 * JavaScript のツリー階層を持ったテーブル表示を行う、ツリーテーブル表示クラスです。
    031 *
    032 * AbstractViewForm により、setter/getterメソッドのデフォルト実装を提供しています。
    033 * 各HTMLのタグに必要な setter/getterメソッドのみ，追加定義しています。
    034 *
    035 * AbstractViewForm を継承している為,ロケールに応じたラベルを出力させる事が出来ます。
    036 *
    037 * @og.group 画面表示
    038 *
    039 * @version  4.0
    040 * @author   Hiroki Nakamura
    041 * @since    JDK5.0,
    042 */
    043public class ViewForm_HTMLAjaxTreeTable extends ViewForm_HTMLCustomTable  {
    044        //* このプログラムのVERSION文字列を設定します。   {@value} */
    045        private static final String VERSION = "4.3.7.4 (2009/07/01)" ;
    046
    047        private static final String JSP = HybsSystem.sys( "JSP" );
    048
    049        private int[]                   childSearchKeys = null;
    050        private String                  childSearchJsp  = null;
    051        private String                  levelClm                = null;
    052        private int                             levelClmPos             = -1;
    053        private String                  imgCollapsed    = null;
    054        private String                  imgExpanded     = null;
    055        private String                  imgNoSub        = null;
    056        private boolean                 expandAll               = false; // 4.3.3.0 (2008/10/01)
    057        private int                             childViewStartNo= -1; // 4.3.3.0 (2008/10/01)
    058//      private String                  expCtrlClm              = null; // 4.3.5.0 (2008/02/01)
    059        private int                             expCtrlClmPos   = -1; // 4.3.5.0 (2008/02/01)
    060
    061        // 4.3.4.4 (2009/01/01)
    062//      /**
    063//       * デフォルトコンストラクター
    064//       *
    065//       */
    066//      public ViewForm_HTMLAjaxTreeTable() {
    067//              super();
    068//      }
    069
    070        /**
    071         * DBTableModel から HTML文字列を作成して返します。
    072         * startNo(表示開始位置)から、pageSize(表示件数)までのView文字列を作成します。
    073         * 表示残りデータが pageSize 以下の場合は,残りのデータをすべて出力します。
    074         *
    075         * @og.rev 4.3.3.0 (2008/10/01) noTransition属性,childViewStartNo属性対応
    076         * @og.rev 4.3.7.4 (2009/07/01) tbodyタグの入れ子を解消(FireFox対応)
    077         *
    078         * @param  strNo     表示開始位置
    079         * @param  pageSize  表示件数
    080         *
    081         * @return  DBTableModelから作成された HTML文字列
    082         */
    083        @Override
    084        public String create( final int strNo, final int pageSize )  {
    085                if( getRowCount() == 0 ) { return ""; } // 暫定処置
    086
    087                initParam();
    088
    089                // 4.3.3.0 (2008/10/01) 子データ差分取得用
    090                int startNo = 0;
    091                if( childViewStartNo >= 0 )  { startNo = childViewStartNo; }
    092                else                                            { startNo = strNo; }
    093
    094                int lastNo = getLastNo( startNo, pageSize );
    095
    096                StringBuilder out = new StringBuilder( HybsSystem.BUFFER_LARGE );
    097
    098                if( headerFormat == null ) {
    099                        makeDefaultFormat();
    100                }
    101
    102                headerFormat.makeFormat( getDBTableModel() );
    103
    104                out.append( getCountForm( startNo,pageSize ) );
    105                out.append( getHeader() );
    106
    107                if( bodyFormatsCount == 0 ) {
    108                        bodyFormats = new TableFormatter[BODYFORMAT_MAX_COUNT];
    109                        bodyFormats[0] = headerFormat ;
    110                        bodyFormatsCount ++ ;
    111                }
    112                else {
    113                        for( int i=0; i<bodyFormatsCount; i++ ) {
    114                                bodyFormats[i].makeFormat( getDBTableModel() );
    115                        }
    116                }
    117
    118//              out.append("<tbody>").append( HybsSystem.CR ); // 4.3.7.4 (2009/07/01)
    119                int bgClrCnt = 0;
    120                for( int row=startNo; row<lastNo; row++ ) {
    121//                      if( isSkip( row ) ) { continue; }               // 3.5.3.1 (2003/10/31)
    122                        if( isSkip( row ) || isSkipNoEdit( row ) ) { continue; } // 4.3.1.0 (2008/09/08)
    123                        for( int i=0; i<bodyFormatsCount; i++ ) {
    124                                TableFormatter bodyFormat = bodyFormats[i];
    125                                if( ! bodyFormat.isUse( row,getDBTableModel() ) ) { continue; }         // 3.5.4.0 (2003/11/25)
    126                                out.append("<tbody").append( getBgColorCycleClass( bgClrCnt++,row ) );
    127                                if( isNoTransition() ) { // 4.3.3.0 (2008/10/01)
    128                                        out.append( getHiddenRowValue( row ) );
    129                                }
    130                                out.append(">");     // 3.7.0.3 (2005/03/01)
    131                                out.append( bodyFormat.getTrTag() );
    132
    133                                if( isNumberDisplay() ) {
    134                                        String ckboxTD = "<td" + bodyFormat.getRowspan() + ">";
    135                                        out.append( makeCheckbox( ckboxTD,row,0 ) );
    136                                }
    137
    138                                int cl = 0;
    139                                for( ; cl < bodyFormat.getLocationSize(); cl++ ) {
    140                                        String fmt = bodyFormat.getFormat(cl);
    141                                        int loc = bodyFormat.getLocation(cl);
    142                                        if( ! bodyFormat.isNoClass() && loc >= 0 ) {
    143                                                StringBuilder newtg = new StringBuilder( HybsSystem.BUFFER_LARGE );
    144                                                newtg.append("<td class=\"");
    145                                                newtg.append( getColumnDbType(loc) );
    146                                                newtg.append("\" ");
    147                                                String tdclass = newtg.toString();
    148                                                fmt = StringUtil.replace( bodyFormat.getFormat(cl) ,"<td", tdclass );
    149                                        }
    150                                        out.append( fmt );
    151                                        if( loc >= 0 ) {
    152                                                if( levelClm != null && levelClm.equals( getDBColumn( loc ).getName() ) ) {
    153                                                        out.append( getLvlClmTag( row ) );
    154                                                }
    155                                                else {
    156                                                        switch( bodyFormat.getType(cl) ) {
    157                                                                case '#' : out.append( getColumnLabel(loc) );           break;
    158                                                                case '$' : out.append( getRendererValue(row,loc) );     break;
    159                                                                case '!' : out.append( getValue(row,loc) );                     break;
    160                                                                default  : out.append( getValueLabel(row,loc) );        break;
    161                                                        }
    162                                                }
    163                                        }
    164                                        else {
    165                                                out.append( bodyFormat.getSystemFormat(row,loc) );
    166                                        }
    167                                }
    168                                out.append( bodyFormat.getFormat(cl) );
    169                                out.append("</tbody>").append( HybsSystem.CR );
    170                        }
    171
    172//                      if( hsc > 0 && hscCnt % hsc == 0 ) {
    173//                              out.append("<tbody class=\"row_h\"").append(" >");
    174//                              out.append( getHeadLine() );
    175//                              out.append("</tbody>");
    176//                              hscCnt = 1;
    177//                      }
    178//                      else {
    179//                              hscCnt ++ ;
    180//                      }
    181                }
    182
    183                if( footerFormat != null ) {
    184                        out.append( getTableFoot() );
    185                }
    186
    187//              out.append("</tbody>").append( HybsSystem.CR ); // 4.3.7.4 (2009/07/01)
    188                out.append("</table>").append( HybsSystem.CR );
    189
    190                out.append( getScrollBarEndDiv() );
    191
    192                out.append( getParameterTag() );
    193
    194                return out.toString();
    195        }
    196
    197        /**
    198         * フォーマットを設定します。
    199         *
    200         * @param       list    TableFormatterのリスト
    201         */
    202        @Override
    203        public void setFormatterList( final List<TableFormatter> list ) {         // 4.3.3.6 (2008/11/15) Generics警告対応
    204                bodyFormats = new TableFormatter[BODYFORMAT_MAX_COUNT];
    205
    206                bodyFormatsCount = 0;
    207                for( int i=0; i<list.size(); i++ ) {
    208                        TableFormatter format = list.get( i );          // 4.3.3.6 (2008/11/15) Generics警告対応
    209                        switch( format.getFormatType() ) {
    210                                case TYPE_HEAD : headerFormat = format; break;
    211                                case TYPE_BODY : bodyFormats[bodyFormatsCount++] = format; break;
    212                                case TYPE_FOOT : footerFormat = format; break;
    213                                default : String errMsg = "FormatterType の定義外の値が指定されました。";
    214                                // 4.3.4.4 (2009/01/01)
    215                                  throw new HybsSystemException( errMsg );
    216                        }
    217                }
    218
    219//              if( headerFormat == null ) {
    220//                      String errMsg = "og:thead タグの、フォーマットの指定は必須です。";
    221//                      throw new HybsSystemException( errMsg );
    222//              }
    223        }
    224
    225        /**
    226         * フォーマッターが設定されていない場合は、DBTableModelの情報からデフォルトの
    227         * フォーマッターを作成します。
    228         *
    229         * @og.rev 4.3.3.6 (2008/11/15) columnDisplay,noDisplay対応
    230         * @og.rev 4.3.5.0 (2008/02/01) 全展開コントロール用カラムへの対応
    231         */
    232        private void makeDefaultFormat() {
    233                StringBuilder buf = new StringBuilder();
    234                String[] clms = getDBTableModel().getNames();
    235                buf.append( "<tr>" );
    236                for ( int i = 0; i < clms.length; i++ ) {
    237                        if( isColumnDisplay( i ) && i != expCtrlClmPos ) { // 4.3.3.6 (2008/11/15) // 4.3.5.0 (2008/02/01)
    238                                buf.append( "<td>[" + clms[i] + "]</td>" );
    239                        }
    240                }
    241                buf.append( "</tr>" );
    242
    243                TableFormatter formatter = new TableFormatter();
    244                formatter.setFormat( buf.toString() );
    245                formatter.setFormatType( FormatterType.TYPE_HEAD );
    246
    247                headerFormat = formatter;
    248        }
    249
    250        /**
    251         * フォーマットメソッドを使用できるかどうかを問い合わせます。
    252         *
    253         * @return      フォーマットメソッドを使用できるか
    254         */
    255        @Override
    256        public boolean canUseFormat() {
    257                return true;
    258        }
    259
    260        /**
    261         * 初期パラメーターを設定します。
    262         *
    263         * @og.rev 4.3.3.0 (2008/10/01) 初期全展開の属性追加
    264         * @og.rev 4.3.5.0 (2008/02/01) 全展開時の状態をコントロールするためのフラグを追加
    265         */
    266        private void initParam() {
    267                String[] tmp    = StringUtil.csv2Array( getParam( ViewAjaxTreeTableParam.CHILD_SEARCH_KEYS, "" ) );
    268                childSearchKeys = new int[tmp.length];
    269                for( int i=0; i<tmp.length; i++ ) {
    270                        childSearchKeys[i] = getDBTableModel().getColumnNo( tmp[i] );
    271                }
    272                childSearchJsp  = getParam( ViewAjaxTreeTableParam.CHILD_SEARCH_JSP, "getChildTag.jsp" );
    273                levelClm                = getParam( ViewAjaxTreeTableParam.LVL_CLM_KEY, "LVL" );
    274                levelClmPos             = getDBTableModel().getColumnNo( levelClm );
    275                imgCollapsed    = getParam( ViewAjaxTreeTableParam.IMG_COLLAPSED, "collapsed.gif" );
    276                imgExpanded     = getParam( ViewAjaxTreeTableParam.IMG_EXPANDED, "expanded.gif" );
    277                imgNoSub        = getParam( ViewAjaxTreeTableParam.IMG_NO_SUB, "nosub.gif" );
    278                expandAll               = Boolean.valueOf( getParam( ViewAjaxTreeTableParam.EXPAND_ALL, "false" ) ); // 4.3.2.0 (2008/09/11)
    279                childViewStartNo= Integer.valueOf( getParam( ViewAjaxTreeTableParam.CHILD_VIEW_START_NO, "-1" ) ); // 4.3.3.0 (2008/10/01)
    280//              expCtrlClm              = getParam( ViewAjaxTreeTableParam.EXPAND_CONTROL_CLM_KEY, "EXPAND_CONTROL" ); // 4.3.5.0 (2008/02/01)
    281                String expCtrlClm       = getParam( ViewAjaxTreeTableParam.EXPAND_CONTROL_CLM_KEY, "EXPAND_CONTROL" ); // 4.3.5.0 (2008/02/01)
    282                expCtrlClmPos   = getDBTableModel().getColumnNo( expCtrlClm, false );
    283        }
    284
    285        /**
    286         * JavaScriptに渡すためのパラメータをhiddenタグで出力します。
    287         *
    288         * @og.rev 4.3.3.0 (2008/10/01) 初期全展開対応
    289         * @og.rev 4.3.5.0 (2008/02/01) 全展開時の状態をコントロールするためのフラグを追加
    290         *
    291         * @param row 行番号
    292         *
    293         * @return HTMLタグ
    294         */
    295        private String getLvlClmTag( final int row ) {
    296                StringBuilder keys = new StringBuilder();
    297                keys.append( "command," + levelClm );
    298                for( int i=0; i<childSearchKeys.length; i++ ) {
    299                        keys.append( "," ).append( getColumnName( childSearchKeys[i] ) );
    300                }
    301
    302                StringBuilder vals = new StringBuilder();
    303                vals.append( "NEW," + getValue( row, levelClmPos ) );
    304                for( int i=0; i<childSearchKeys.length; i++ ) {
    305                        vals.append( "," ).append( getValue( row, childSearchKeys[i] ) );
    306                }
    307
    308                String imgsrc = null;
    309                StringBuilder clazz = new StringBuilder();
    310                clazz.append( "lvlctl unreplaceable" );
    311                if( expandAll ) { // 4.3.3.0 (2008/10/01)
    312                        if( row == getRowCount() - 1
    313                                        || Integer.parseInt( getValue( row, levelClmPos ) ) >= Integer.parseInt( getValue( row+1, levelClmPos ) ) ) {
    314                                boolean isExp = ( expCtrlClmPos > -1 && StringUtil.nval( getValue( row, expCtrlClmPos ), false ) );
    315                                if( isExp ) {
    316                                        imgsrc = JSP + "/image/" + imgCollapsed;
    317                                }
    318                                else {
    319                                        imgsrc = JSP + "/image/" + imgNoSub;
    320                                        clazz.append( " fetched nosub" );
    321                                }
    322                        }
    323                        else {
    324                                imgsrc = JSP + "/image/" + imgExpanded;
    325                                clazz.append( " fetched expanded" );
    326                        }
    327                }
    328                else {
    329                        imgsrc = JSP + "/image/" + imgCollapsed;
    330                }
    331
    332                TagBuffer tag = new TagBuffer( "img" );
    333                tag.add( "class", clazz.toString() );
    334                tag.add( "src" , imgsrc );
    335                tag.add( "alt" , "Level " + getValue( row, levelClmPos ) );
    336                tag.add( "lvl" , getValue( row, levelClmPos ) );
    337                tag.add( "keys" , keys.toString() );
    338                tag.add( "vals" , vals.toString() );
    339
    340                return getRendererValue( row, levelClmPos ) + tag.makeTag();
    341        }
    342
    343        /**
    344         * JavaScriptに渡すためのパラメーターをhiddenタグをして出力します。
    345         *
    346         * @return hiddenタグ
    347         */
    348        private String getParameterTag() {
    349                StringBuilder buf = new StringBuilder();
    350                buf.append( XHTMLTag.hidden( ViewAjaxTreeTableParam.CHILD_SEARCH_JSP, childSearchJsp ) );
    351                buf.append( XHTMLTag.hidden( ViewAjaxTreeTableParam.IMG_COLLAPSED, JSP + "/image/" + imgCollapsed ) );
    352                buf.append( XHTMLTag.hidden( ViewAjaxTreeTableParam.IMG_EXPANDED, JSP + "/image/" + imgExpanded ) );
    353                buf.append( XHTMLTag.hidden( ViewAjaxTreeTableParam.IMG_NO_SUB, JSP + "/image/" + imgNoSub ) );
    354                return buf.toString();
    355        }
    356}