2 * Copyright (c) 2009 The openGion Project.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13 * either express or implied. See the License for the specific language
14 * governing permissions and limitations under the License.
16 package org.opengion.plugin.view;
18 import java.util.List;
20 import org.opengion.fukurou.util.StringUtil;
21 import org.opengion.fukurou.util.TagBuffer;
22 import org.opengion.fukurou.util.XHTMLTag;
23 import org.opengion.hayabusa.common.HybsSystem;
24 import org.opengion.hayabusa.common.HybsSystemException;
25 import org.opengion.hayabusa.html.FormatterType;
26 import org.opengion.hayabusa.html.TableFormatter;
27 import org.opengion.hayabusa.html.ViewAjaxTreeTableParam;
30 * JavaScript のツリー階層を持ったテーブル表示を行う、ツリーテーブル表示クラスです。
32 * AbstractViewForm により、setter/getterメソッドのデフォルト実装を提供しています。
33 * 各HTMLのタグに必要な setter/getterメソッドのみ、追加定義しています。
35 * AbstractViewForm を継承している為、ロケールに応じたラベルを出力させる事が出来ます。
37 * @og.rev 7.3.2.3 (2021/04/09) システム定数のJSP_IMGを使用します。(※ SYS.JSP + SYS.IMAGE_DIR)
41 * @author Hiroki Nakamura
44 public class ViewForm_HTMLAjaxTreeTable extends ViewForm_HTMLCustomTable {
45 /** このプログラムのVERSION文字列を設定します。 {@value} */
46 private static final String VERSION = "8.0.3.0 (2021/12/17)" ;
48 // // 6.4.4.2 (2016/04/01) JSP + "/image/" にする。
49 // private static final String JSPIMG = HybsSystem.sys( "JSP" ) + "/image/" ;
50 // 8.0.3.0 (2021/12/17) hayabusa.taglib.ViewAjaxTreeParamTag へ移動
51 private static final String JSPIMG = HybsSystem.sys( "JSP_IMG" ) + "/" ; // 互換性の関係で最後に"/"を追加
53 private int[] childSearchKeys ;
54 private String childSearchJsp ;
55 private String levelClm ;
56 private int levelClmPos = -1;
57 private String imgCollapsed ;
58 private String imgExpanded ;
59 private String imgNoSub ;
60 private boolean expandAll ; // 4.3.3.0 (2008/10/01)
61 private int childViewStartNo= -1; // 4.3.3.0 (2008/10/01)
62 private int expCtrlClmPos = -1; // 4.3.5.0 (2008/02/01)
67 * @og.rev 6.4.2.0 (2016/01/29) PMD refactoring. Each class should declare at least one constructor.
69 public ViewForm_HTMLAjaxTreeTable() { super(); } // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。
72 * DBTableModel から HTML文字列を作成して返します。
73 * startNo(表示開始位置)から、pageSize(表示件数)までのView文字列を作成します。
74 * 表示残りデータが pageSize 以下の場合は、残りのデータをすべて出力します。
76 * @og.rev 4.3.3.0 (2008/10/01) noTransition属性,childViewStartNo属性対応
77 * @og.rev 4.3.7.4 (2009/07/01) tbodyタグの入れ子を解消(FireFox対応)
78 * @og.rev 6.4.3.4 (2016/03/11) tdに、[カラム]が無いケースで、次の[カラム]のクラス属性が、前方すべてのtdにセットされてしまう対応。
79 * @og.rev 6.4.4.2 (2016/04/01) TableFormatterのタイプ別値取得処理の共通部をまとめる。
80 * @og.rev 6.4.5.0 (2016/04/08) メソッド変更( getColumnDbType(int) → getClassName(int) )
81 * @og.rev 6.8.1.1 (2017/07/22) ckboxTD変数は、<td> から <td に変更します(タグの最後が記述されていない状態でもらう)。
84 * @param pageSize 表示件数
86 * @return DBTableModelから作成された HTML文字列
90 public String create( final int strNo, final int pageSize ) {
91 if( getRowCount() == 0 ) { return ""; } // 暫定処置
95 // 4.3.3.0 (2008/10/01) 子データ差分取得用
96 // 6.3.9.1 (2015/11/27) Found 'DD'-anomaly for variable(PMD)
97 final int startNo = childViewStartNo >= 0 ? childViewStartNo : strNo;
99 if( headerFormat == null ) {
103 headerFormat.makeFormat( getDBTableModel() );
105 final StringBuilder out = new StringBuilder( BUFFER_LARGE )
106 .append( getCountForm( startNo,pageSize ) )
107 .append( getHeader() );
109 if( bodyFormatsCount == 0 ) {
110 bodyFormats = new TableFormatter[BODYFORMAT_MAX_COUNT];
111 bodyFormats[0] = headerFormat ;
112 bodyFormatsCount ++ ;
115 for( int i=0; i<bodyFormatsCount; i++ ) {
116 bodyFormats[i].makeFormat( getDBTableModel() );
121 final int lastNo = getLastNo( startNo, pageSize ); // 6.3.9.1 (2015/11/27) forループの近くに移動
122 for( int row=startNo; row<lastNo; row++ ) {
123 if( isSkip( row ) || isSkipNoEdit( row ) ) { continue; } // 4.3.1.0 (2008/09/08)
124 for( int i=0; i<bodyFormatsCount; i++ ) {
125 final TableFormatter bodyFormat = bodyFormats[i];
126 if( ! bodyFormat.isUse( row,getDBTableModel() ) ) { continue; } // 3.5.4.0 (2003/11/25)
127 out.append("<tbody").append( getBgColorCycleClass( bgClrCnt++,row ) );
128 if( isNoTransition() ) { // 4.3.3.0 (2008/10/01)
129 out.append( getHiddenRowValue( row ) );
131 out.append('>') // 6.0.2.5 (2014/10/31) char を append する。
132 .append( bodyFormat.getTrTag() );
134 if( isNumberDisplay() ) {
135 final String ckboxTD = "<td" + bodyFormat.getRowspan(); // 6.8.1.1 (2017/07/22)
136 out.append( makeCheckbox( ckboxTD,row,0 ) );
140 for( ; cl<bodyFormat.getLocationSize(); cl++ ) {
141 String fmt = bodyFormat.getFormat(cl);
142 final int loc = bodyFormat.getLocation(cl);
143 if( ! bodyFormat.isNoClass() && loc >= 0 ) {
144 // 6.4.3.4 (2016/03/11) tdに、[カラム]が無いケースで、次の[カラム]のクラス属性が、前方すべてのtdにセットされてしまう対応。
145 final int idx = fmt.lastIndexOf( "<td" );
146 if( idx >= 0 ) { // matchしてるので、あるはず
147 final String tdclass = " class=\"" + getClassName(loc) + "\" "; // 6.4.5.0 (2016/04/08)
148 fmt = fmt.substring( 0,idx+3 ) + tdclass + fmt.substring( idx+3 ) ;
153 if( levelClm != null && levelClm.equals( getDBColumn( loc ).getName() ) ) {
154 out.append( getLvlClmTag( row ) );
157 // 6.4.4.2 (2016/04/01) 処理の共通部をまとめる。
158 out.append( getTypeCaseValue( bodyFormat.getType(cl),row,loc ) );
162 out.append( bodyFormat.getSystemFormat(row,loc) );
165 out.append( bodyFormat.getFormat(cl) )
166 .append("</tbody>").append( CR );
170 if( footerFormat != null ) {
171 // 6.3.9.0 (2015/11/06) 引数にTableFormatterを渡して、処理の共有化を図る。
172 out.append( getTableFoot( footerFormat ) );
175 out.append("</table>").append( CR )
176 .append( getScrollBarEndDiv() )
177 .append( getParameterTag() );
179 return out.toString();
185 * @param list TableFormatterのリスト
188 public void setFormatterList( final List<TableFormatter> list ) { // 4.3.3.6 (2008/11/15) Generics警告対応
189 bodyFormats = new TableFormatter[BODYFORMAT_MAX_COUNT];
191 bodyFormatsCount = 0;
192 // 7.2.9.4 (2020/11/20) PMD:This for loop can be replaced by a foreach loop
193 for( final TableFormatter format : list ) {
194 // for( int i=0; i<list.size(); i++ ) {
195 // final TableFormatter format = list.get( i ); // 4.3.3.6 (2008/11/15) Generics警告対応
196 switch( format.getFormatType() ) {
197 case TYPE_HEAD : headerFormat = format; break;
198 case TYPE_BODY : bodyFormats[bodyFormatsCount++] = format; break;
199 case TYPE_FOOT : footerFormat = format; break;
200 default : final String errMsg = "FormatterType の定義外の値が指定されました。";
201 // 4.3.4.4 (2009/01/01)
202 throw new HybsSystemException( errMsg );
208 * フォーマッターが設定されていない場合は、DBTableModelの情報からデフォルトの
211 * @og.rev 4.3.3.6 (2008/11/15) columnDisplay,noDisplay対応
212 * @og.rev 4.3.5.0 (2008/02/01) 全展開コントロール用カラムへの対応
214 private void makeDefaultFormat() {
215 final String[] clms = getDBTableModel().getNames();
216 final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE )
218 for( int i=0; i<clms.length; i++ ) {
219 if( isColumnDisplay( i ) && i != expCtrlClmPos ) { // 4.3.3.6 (2008/11/15) // 4.3.5.0 (2008/02/01)
220 buf.append( "<td>[" ).append( clms[i] ).append( "]</td>" ); // 6.4.4.2 (2016/04/01)
223 buf.append( "</tr>" );
225 final TableFormatter formatter = new TableFormatter();
226 formatter.setFormat( buf.toString() );
227 formatter.setFormatType( FormatterType.TYPE_HEAD );
229 headerFormat = formatter;
233 * フォーマットメソッドを使用できるかどうかを問い合わせます。
235 * @return フォーマットメソッドを使用できるか
238 public boolean canUseFormat() {
245 * @og.rev 4.3.3.0 (2008/10/01) 初期全展開の属性追加
246 * @og.rev 4.3.5.0 (2008/02/01) 全展開時の状態をコントロールするためのフラグを追加
247 * @og.rev 8.0.3.0 (2021/12/17) JSPIMG の連結に、StringUtil.urlAppend を使用する。
249 private void initParam() {
250 final String[] tmp = StringUtil.csv2Array( getParam( ViewAjaxTreeTableParam.CHILD_SEARCH_KEYS, "" ) );
251 childSearchKeys = new int[tmp.length];
252 for( int i=0; i<tmp.length; i++ ) {
253 childSearchKeys[i] = getDBTableModel().getColumnNo( tmp[i] );
255 childSearchJsp = getParam( ViewAjaxTreeTableParam.CHILD_SEARCH_JSP, "getChildTag.jsp" );
256 levelClm = getParam( ViewAjaxTreeTableParam.LVL_CLM_KEY, "LVL" );
257 levelClmPos = getDBTableModel().getColumnNo( levelClm );
258 // imgCollapsed = getParam( ViewAjaxTreeTableParam.IMG_COLLAPSED, "collapsed.gif" );
259 // imgExpanded = getParam( ViewAjaxTreeTableParam.IMG_EXPANDED, "expanded.gif" );
260 // imgNoSub = getParam( ViewAjaxTreeTableParam.IMG_NO_SUB, "nosub.gif" );
261 imgCollapsed = StringUtil.urlAppend( JSPIMG, getParam( ViewAjaxTreeTableParam.IMG_COLLAPSED, "collapsed.gif" ) ); // 8.0.3.0 (2021/12/17)
262 imgExpanded = StringUtil.urlAppend( JSPIMG, getParam( ViewAjaxTreeTableParam.IMG_EXPANDED, "expanded.gif" ) ); // 8.0.3.0 (2021/12/17)
263 imgNoSub = StringUtil.urlAppend( JSPIMG, getParam( ViewAjaxTreeTableParam.IMG_NO_SUB, "nosub.gif" ) ); // 8.0.3.0 (2021/12/17)
264 expandAll = Boolean.valueOf( getParam( ViewAjaxTreeTableParam.EXPAND_ALL, "false" ) ); // 4.3.2.0 (2008/09/11)
265 childViewStartNo= Integer.parseInt( getParam( ViewAjaxTreeTableParam.CHILD_VIEW_START_NO, "-1" ) ); // 6.0.2.4 (2014/10/17) メソッド間違い
266 final String expCtrlClm = getParam( ViewAjaxTreeTableParam.EXPAND_CONTROL_CLM_KEY, "EXPAND_CONTROL" ); // 4.3.5.0 (2008/02/01)
267 expCtrlClmPos = getDBTableModel().getColumnNo( expCtrlClm, false );
271 * JavaScriptに渡すためのパラメータをhiddenタグで出力します。
273 * @og.rev 4.3.3.0 (2008/10/01) 初期全展開対応
274 * @og.rev 4.3.5.0 (2008/02/01) 全展開時の状態をコントロールするためのフラグを追加
275 * @og.rev 6.4.2.0 (2016/01/29) alt属性にtitle属性を追記。
276 * @og.rev 6.4.3.4 (2016/03/11) forループを、2回まわさずに、1回にまとめます。
277 * @og.rev 8.0.3.0 (2021/12/17) JSPIMG の連結に、StringUtil.urlAppend を使用する。
284 private String getLvlClmTag( final int row ) {
285 // 6.4.2.0 (2016/01/29) ソースを見ていたら、共通値が結構あったので、再利用します。
286 final String lvlClmVal = getValue( row, levelClmPos );
288 // 6.4.3.4 (2016/03/11) forループを、2回まわさずに、1回にまとめます。
289 final StringBuilder keys = new StringBuilder( BUFFER_MIDDLE ).append( "command," ).append( levelClm );
290 final StringBuilder vals = new StringBuilder( BUFFER_MIDDLE ).append( "NEW," ).append( lvlClmVal );
292 // 7.2.9.4 (2020/11/20) PMD:This for loop can be replaced by a foreach loop
293 for( final int clm : childSearchKeys ) {
294 // for( int i=0; i<childSearchKeys.length; i++ ) {
295 // final int clm = childSearchKeys[i];
296 keys.append( ',' ).append( getColumnName( clm ) ); // 6.0.2.5 (2014/10/31) char を append する。
297 vals.append( ',' ).append( getValue( row, clm ) ); // 6.0.2.5 (2014/10/31) char を append する。
300 // 6.3.9.1 (2015/11/27) Found 'DD'-anomaly for variable(PMD)
301 final String imgsrc ;
302 final StringBuilder clazz = new StringBuilder( BUFFER_MIDDLE );
303 clazz.append( "lvlctl unreplaceable" );
304 if( expandAll ) { // 4.3.3.0 (2008/10/01)
305 if( row == getRowCount() - 1
306 || Integer.parseInt( lvlClmVal ) >= Integer.parseInt( getValue( row+1, levelClmPos ) ) ) { // 6.4.2.0 (2016/01/29)
307 final boolean isExp = expCtrlClmPos > -1 && StringUtil.nval( getValue( row, expCtrlClmPos ), false ) ;
309 // imgsrc = JSPIMG + imgCollapsed;
310 imgsrc = imgCollapsed; // 8.0.3.0 (2021/12/17)
313 // imgsrc = JSPIMG + imgNoSub;
314 imgsrc = imgNoSub; // 8.0.3.0 (2021/12/17)
315 clazz.append( " fetched nosub" );
319 // imgsrc = JSPIMG + imgExpanded;
320 imgsrc = imgExpanded; // 8.0.3.0 (2021/12/17)
321 clazz.append( " fetched expanded" );
325 // imgsrc = JSPIMG + imgCollapsed;
326 imgsrc = imgCollapsed; // 8.0.3.0 (2021/12/17)
329 // 6.4.2.0 (2016/01/29) alt属性にtitle属性を追記。
330 final String tag = new TagBuffer( "img" ) // 6.1.1.0 (2015/01/17) refactoring. 連結記述
331 .add( "class" , clazz.toString() )
332 .add( "src" , imgsrc )
333 .add( "alt" , "Level " + lvlClmVal ) // 6.4.2.0 (2016/01/29) 共通値を設定する。
334 .add( "title" , "Level " + lvlClmVal ) // 6.4.2.0 (2016/01/29) alt属性にtitle属性を追記。
335 .add( "lvl" , lvlClmVal ) // 6.4.2.0 (2016/01/29) 共通値を設定する。
336 .add( "keys" , keys.toString() )
337 .add( "vals" , vals.toString() )
340 return getRendererValue( row, levelClmPos ) + tag;
344 * JavaScriptに渡すためのパラメーターをhiddenタグをして出力します。
346 * @og.rev 8.0.3.0 (2021/12/17) JSPIMG の連結に、StringUtil.urlAppend を使用する。
351 private String getParameterTag() {
352 final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE )
353 .append( XHTMLTag.hidden( ViewAjaxTreeTableParam.CHILD_SEARCH_JSP, childSearchJsp ) )
354 // .append( XHTMLTag.hidden( ViewAjaxTreeTableParam.IMG_COLLAPSED, JSPIMG + imgCollapsed ) )
355 // .append( XHTMLTag.hidden( ViewAjaxTreeTableParam.IMG_EXPANDED, JSPIMG + imgExpanded ) )
356 // .append( XHTMLTag.hidden( ViewAjaxTreeTableParam.IMG_NO_SUB, JSPIMG + imgNoSub ) );
357 .append( XHTMLTag.hidden( ViewAjaxTreeTableParam.IMG_COLLAPSED, imgCollapsed ) ) // 8.0.3.0 (2021/12/17)
358 .append( XHTMLTag.hidden( ViewAjaxTreeTableParam.IMG_EXPANDED, imgExpanded ) ) // 8.0.3.0 (2021/12/17)
359 .append( XHTMLTag.hidden( ViewAjaxTreeTableParam.IMG_NO_SUB, imgNoSub ) ); // 8.0.3.0 (2021/12/17)
360 return buf.toString();