OSDN Git Service

Ver8.5.2.0
[opengion/opengionV8.git] / uap / webapps / gf / src / org / opengion / plugin / view / ViewForm_HTMLAjaxTreeTable.java
1 /*
2  * Copyright (c) 2009 The openGion Project.
3  *
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
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 package org.opengion.plugin.view;
17
18 import java.util.List;
19
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;
28
29 /**
30  * JavaScript のツリー階層を持ったテーブル表示を行う、ツリーテーブル表示クラスです。
31  *
32  * AbstractViewForm により、setter/getterメソッドのデフォルト実装を提供しています。
33  * 各HTMLのタグに必要な setter/getterメソッドのみ、追加定義しています。
34  *
35  * AbstractViewForm を継承している為、ロケールに応じたラベルを出力させる事が出来ます。
36  *
37  * @og.rev 7.3.2.3 (2021/04/09) システム定数のJSP_IMGを使用します。(※ SYS.JSP + SYS.IMAGE_DIR)
38  * @og.group 画面表示
39  *
40  * @version  4.0
41  * @author   Hiroki Nakamura
42  * @since    JDK5.0,
43  */
44 public class ViewForm_HTMLAjaxTreeTable extends ViewForm_HTMLCustomTable  {
45         /** このプログラムのVERSION文字列を設定します。       {@value} */
46         private static final String VERSION = "8.0.3.0 (2021/12/17)" ;
47
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" ) + "/" ;        // 互換性の関係で最後に"/"を追加
52
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)
63
64         /**
65          * デフォルトコンストラクター
66          *
67          * @og.rev 6.4.2.0 (2016/01/29) PMD refactoring. Each class should declare at least one constructor.
68          */
69         public ViewForm_HTMLAjaxTreeTable() { super(); }                // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。
70
71         /**
72          * DBTableModel から HTML文字列を作成して返します。
73          * startNo(表示開始位置)から、pageSize(表示件数)までのView文字列を作成します。
74          * 表示残りデータが pageSize 以下の場合は、残りのデータをすべて出力します。
75          *
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 に変更します(タグの最後が記述されていない状態でもらう)。
82          *
83          * @param  strNo     表示開始位置
84          * @param  pageSize  表示件数
85          *
86          * @return  DBTableModelから作成された HTML文字列
87          * @og.rtnNotNull
88          */
89         @Override
90         public String create( final int strNo, final int pageSize )  {
91                 if( getRowCount() == 0 ) { return ""; } // 暫定処置
92
93                 initParam();
94
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;
98
99                 if( headerFormat == null ) {
100                         makeDefaultFormat();
101                 }
102
103                 headerFormat.makeFormat( getDBTableModel() );
104
105                 final StringBuilder out = new StringBuilder( BUFFER_LARGE )
106                         .append( getCountForm( startNo,pageSize ) )
107                         .append( getHeader() );
108
109                 if( bodyFormatsCount == 0 ) {
110                         bodyFormats = new TableFormatter[BODYFORMAT_MAX_COUNT];
111                         bodyFormats[0] = headerFormat ;
112                         bodyFormatsCount ++ ;
113                 }
114                 else {
115                         for( int i=0; i<bodyFormatsCount; i++ ) {
116                                 bodyFormats[i].makeFormat( getDBTableModel() );
117                         }
118                 }
119
120                 int bgClrCnt = 0;
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 ) );
130                                 }
131                                 out.append('>')         // 6.0.2.5 (2014/10/31) char を append する。
132                                         .append( bodyFormat.getTrTag() );
133
134                                 if( isNumberDisplay() ) {
135                                         final String ckboxTD = "<td" + bodyFormat.getRowspan();         // 6.8.1.1 (2017/07/22)
136                                         out.append( makeCheckbox( ckboxTD,row,0 ) );
137                                 }
138
139                                 int cl = 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 ) ;
149                                                 }
150                                         }
151                                         out.append( fmt );
152                                         if( loc >= 0 ) {
153                                                 if( levelClm != null && levelClm.equals( getDBColumn( loc ).getName() ) ) {
154                                                         out.append( getLvlClmTag( row ) );
155                                                 }
156                                                 else {
157                                                         // 6.4.4.2 (2016/04/01) 処理の共通部をまとめる。
158                                                         out.append( getTypeCaseValue( bodyFormat.getType(cl),row,loc ) );
159                                                 }
160                                         }
161                                         else {
162                                                 out.append( bodyFormat.getSystemFormat(row,loc) );
163                                         }
164                                 }
165                                 out.append( bodyFormat.getFormat(cl) )
166                                         .append("</tbody>").append( CR );
167                         }
168                 }
169
170                 if( footerFormat != null ) {
171                         // 6.3.9.0 (2015/11/06) 引数にTableFormatterを渡して、処理の共有化を図る。
172                         out.append( getTableFoot( footerFormat ) );
173                 }
174
175                 out.append("</table>").append( CR )
176                         .append( getScrollBarEndDiv() )
177                         .append( getParameterTag() );
178
179                 return out.toString();
180         }
181
182         /**
183          * フォーマットを設定します。
184          *
185          * @param       list    TableFormatterのリスト
186          */
187         @Override
188         public void setFormatterList( final List<TableFormatter> list ) {               // 4.3.3.6 (2008/11/15) Generics警告対応
189                 bodyFormats = new TableFormatter[BODYFORMAT_MAX_COUNT];
190
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 );
203                         }
204                 }
205         }
206
207         /**
208          * フォーマッターが設定されていない場合は、DBTableModelの情報からデフォルトの
209          * フォーマッターを作成します。
210          *
211          * @og.rev 4.3.3.6 (2008/11/15) columnDisplay,noDisplay対応
212          * @og.rev 4.3.5.0 (2008/02/01) 全展開コントロール用カラムへの対応
213          */
214         private void makeDefaultFormat() {
215                 final String[] clms = getDBTableModel().getNames();
216                 final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE )
217                                         .append( "<tr>" );
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)
221                         }
222                 }
223                 buf.append( "</tr>" );
224
225                 final TableFormatter formatter = new TableFormatter();
226                 formatter.setFormat( buf.toString() );
227                 formatter.setFormatType( FormatterType.TYPE_HEAD );
228
229                 headerFormat = formatter;
230         }
231
232         /**
233          * フォーマットメソッドを使用できるかどうかを問い合わせます。
234          *
235          * @return      フォーマットメソッドを使用できるか
236          */
237         @Override
238         public boolean canUseFormat() {
239                 return true;
240         }
241
242         /**
243          * 初期パラメーターを設定します。
244          *
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 を使用する。
248          */
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] );
254                 }
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 );
268         }
269
270         /**
271          * JavaScriptに渡すためのパラメータをhiddenタグで出力します。
272          *
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 を使用する。
278          *
279          * @param row 行番号
280          *
281          * @return HTMLタグ
282          * @og.rtnNotNull
283          */
284         private String getLvlClmTag( final int row ) {
285                 // 6.4.2.0 (2016/01/29) ソースを見ていたら、共通値が結構あったので、再利用します。
286                 final String lvlClmVal = getValue( row, levelClmPos );
287
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 );
291
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 する。
298                 }
299
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 ) ;
308                                 if( isExp ) {
309 //                                      imgsrc = JSPIMG + imgCollapsed;
310                                         imgsrc = imgCollapsed;                          // 8.0.3.0 (2021/12/17)
311                                 }
312                                 else {
313 //                                      imgsrc = JSPIMG + imgNoSub;
314                                         imgsrc = imgNoSub;                                      // 8.0.3.0 (2021/12/17)
315                                         clazz.append( " fetched nosub" );
316                                 }
317                         }
318                         else {
319 //                              imgsrc = JSPIMG + imgExpanded;
320                                 imgsrc = imgExpanded;                                   // 8.0.3.0 (2021/12/17)
321                                 clazz.append( " fetched expanded" );
322                         }
323                 }
324                 else {
325 //                      imgsrc = JSPIMG + imgCollapsed;
326                         imgsrc = imgCollapsed;                                          // 8.0.3.0 (2021/12/17)
327                 }
328
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() )
338                         .makeTag();
339
340                 return getRendererValue( row, levelClmPos ) + tag;
341         }
342
343         /**
344          * JavaScriptに渡すためのパラメーターをhiddenタグをして出力します。
345          *
346          * @og.rev 8.0.3.0 (2021/12/17) JSPIMG の連結に、StringUtil.urlAppend を使用する。
347          *
348          * @return hiddenタグ
349          * @og.rtnNotNull
350          */
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();
361         }
362 }