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