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.view;
017    
018    import java.util.List;
019    
020    import org.opengion.fukurou.util.StringUtil;
021    import org.opengion.fukurou.util.TagBuffer;
022    import org.opengion.fukurou.util.XHTMLTag;
023    import org.opengion.hayabusa.common.HybsSystem;
024    import org.opengion.hayabusa.common.HybsSystemException;
025    import org.opengion.hayabusa.html.FormatterType;
026    import org.opengion.hayabusa.html.TableFormatter;
027    import 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     */
043    public class ViewForm_HTMLAjaxTreeTable extends ViewForm_HTMLCustomTable  {
044            //* こ?プログラ??VERSION??を設定します?       {@value} */
045            private static final String VERSION = "4.3.1.0 (2008/09/08)" ;
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    }