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.io.Serializable;
019 import java.util.Arrays;
020 import java.util.Comparator;
021 import java.util.LinkedHashSet;
022 import java.util.Set;
023 import java.util.TreeSet;
024
025 import org.opengion.fukurou.util.StringUtil;
026 import org.opengion.hayabusa.common.HybsSystem;
027 import org.opengion.hayabusa.common.HybsSystemException;
028 import org.opengion.hayabusa.db.DBColumn;
029 import org.opengion.hayabusa.db.DBColumnConfig;
030 import org.opengion.hayabusa.db.DBTableModel;
031 import org.opengion.hayabusa.db.DBTableModelSorter;
032 import org.opengion.hayabusa.db.DBTableModelUtil;
033 import org.opengion.hayabusa.db.Selection;
034 import org.opengion.hayabusa.html.CrossMap;
035 import org.opengion.hayabusa.html.ViewCrossTableParam;
036 import org.opengion.hayabusa.resource.CodeData;
037 import org.opengion.hayabusa.resource.ResourceManager;
038
039 /**
040 * クロスé›?¨ˆテーブル作æ?クラスですã?
041 *
042 * select dept.dname,emp.deptno,substrb(job,1,2) as X,job,mgr,sum(sal),count(*)
043 * from emp,dept
044 * where emp.deptno = dept.deptno
045 * group by dept.dname,emp.deptno,cube(job,mgr)
046 * order by emp.deptno,job,mgr;
047 *
048 * HEAD1 ?šã?ãƒ?ƒ€ー。前段と同じãƒ??タは表示させなã�??
049 * HEAD2 ?šキーブレイクさせるカラãƒ??またã?前段と同じãƒ??タは表示させなã�??
050 * HEAD3 ?šキーブレイクさせなã�?‚«ラãƒ??またã?前段と同じãƒ??タでも表示させるã?
051 * ROW ?š行データのヘッãƒ??になるカラãƒ?
052 * COL ?šå?ãƒ??タのヘッãƒ??になるカラãƒ??下記ã?SUM1,SUM2の両方のヘッãƒ??になるã?
053 * SUM1 ?šå?ãƒ??タの値になるカラãƒ??
054 * SUM2 ?šå?ãƒ??タの値になるカラãƒ??
055 *
056 * SUMカラãƒ??数、キーブレイクのカラãƒ?��、グループ化するカラãƒ?��ã‚?
057 * æŒ?®šすることで、これらのクロスé›?¨ˆ結果の表示方法をæŒ?®šしますã?
058 *
059 * breakColumn = "DEPTNO" キーブレイクのカラãƒ?��
060 * noGroupColumns = "X" グループ化するカラãƒ?��
061 * sumNumber = "2" SUMカラãƒ??数
062 * cubeXColumn = "JOB" CUBE計算ã??‘つ目(X)カラãƒ?‚’æŒ?®?
063 * cubeYColumn = "MGR" CUBE計算ã??’つ目(Y)カラãƒ?‚’æŒ?®?
064 * cubeSortType = "NUMBER" CUBE Y の列ã?ãƒ?ƒ€ーのソート方法をæŒ?®?
065 * gokeiSortDir = "false" 合計カラãƒ??ソート方向をæŒ?®?初期値:ソートしなã�?
066 * shokeiLabel = "SHOKEI" 列小計ã?カラãƒ?�«表示するラベルID
067 * gokeiLabel = "GOKEI" 列合計ã?カラãƒ?�«表示するラベルID
068 * useHeaderColumn= "false" ヘッãƒ??カラãƒ?�«レンãƒ?ƒ©ー、エãƒ?‚£ターを適用するかをæŒ?®?
069 * useClassAdd = "false" å�??æƒ??のclass属æ?に、カラãƒ?��などを付与するかどã�?�‹を指å®?
070 * useHeaderResource = "false" ヘッãƒ??表示にラベルリソースを利用するã�?
071 *
072 * å�?‚«ラãƒ??属æ?(HEAD,SUMç?を認識する方æ³?
073 *
074 * HEAD1 HEAD2 HEAD3 ROW COL SUM1 SUM2 とã�?�†並びを認識する方法ã?ã€?
075 * 多数の前提条件を利用して、å?来るだけ少なã�?ƒ‘ラメータで自動認è?
076 * させてã�?�¾すã?
077 * 若干ç�?§£しにくいかもしれませんがã?慣れてくださいã€?
078 *
079 * 前提条件??
080 * ROW,COL は、å¿?�š?‘å?ずつ存在するã€?
081 * HEAD群、ROW,COL,SUM群 とã�?�†並びになってã�?‚‹ã€?
082 * SUM群の数は、パラメータでæŒ?®šするã?
083 * 計算方法ï¼?
084 * HEAD数=カラãƒ?•°(7)-SUM数(2)-1(ROW,COLåˆ? ????å€?(0 ??3)
085 * ROWアドレス?�cubeXColumn 設å®? (3) ※ アドレスは?�から始まる為
086 * COLアドレス?�cubeYColumn 設å®? (4)
087 * SUMアドレス?�HEAD数?‹ï¼???カラãƒ?•°(7)-1 (5 ??6)
088 *
089 * @og.rev 3.5.4.0 (2003/11/25) 新規作æ?
090 * @og.group 画面表示
091 *
092 * @version 4.0
093 * @author Kazuhiko Hasegawa
094 * @since JDK5.0,
095 */
096 public class ViewForm_HTMLCrossTable extends ViewForm_HTMLTable {
097 //* こã?プログラãƒ??VERSIONæ–?—å?を設定しますã? {@value} */
098 private static final String VERSION = "5.7.4.3 (2014/03/28)" ;
099
100 private String[] groupByData = null;
101 private String[] groupByCls = null;
102
103 // 3.5.4.8 (2004/02/23) 機è?改å–?
104 private int rowClmNo = -1; // ROWカラãƒ??カラãƒ?•ª号
105 private int colClmNo = -1; // CLMカラãƒ??カラãƒ?•ª号
106 private int headCount = 0; // HEADカラãƒ??数
107 private int sumCount = 1; // 合計カラãƒ??数
108 private int breakClmNo = -1; // ブレークするカラãƒ??カラãƒ?•ª号
109 private boolean[] noGroupClm = null; // グループ化する/しなã�??フラグ配å?
110 private String shokeiLabel = "小è¨?; // 列小計ã?カラãƒ?�«表示するラベルID
111 private String gokeiLabel = "合è¨?; // 列合計ã?カラãƒ?�«表示するラベルID
112 private String gokeiSortDir = null; // 列合計ã?カラãƒ?‚’ソートする方å�?
113
114 // 3.5.6.3 (2004/07/12) ソート方式[STRING,NUMBER,LOAD]
115 private String cubeSortType = "LOAD";
116
117 private DBTableModel table2 = null;
118 private boolean firstStep = true;
119
120 private String[] clmKeys = null; // é›?¨ˆ部のカラãƒ?‚ー(é›?¨ˆカラãƒ?�Œè¤?•°でもä¸?�¤)の配å?
121 private String[] clsAdd = null; // 5.2.2.0 (2010/11/01) class属æ?に付与されるカラãƒ?‚ー
122
123 private String noDisplayKeys = null; // 3.7.0.4 (2005/03/18)
124 private String columnDisplayKeys = null; // 5.2.2.0 (2010/11/01)
125
126 private boolean firstClmGokei = false; // 5.0.0.3 (2009/09/22)
127 private boolean useHeaderColumn = false; // 5.2.2.0 (2010/11/01)
128 private boolean useClassAdd = false; // 5.2.2.0 (2010/11/01) class属æ?にカラãƒ?‚ーを追åŠ?�™るかどã�?�‹
129 private boolean useHeaderResource = false; // 5.5.5.0 (2012/07/28)
130 private String headerCode = null; // 5.5.5.0 (2012/07/28)
131
132 /**
133 * 初期化しますã?
134 * ここでは、å?部で使用されてã�?‚‹キャãƒ?‚·ュをクリアしã?
135 * 新しいモãƒ?ƒ«(DBTableModel)とè¨?ª?lang) をå?にå†?ƒ¨ãƒ??タをå?構築しますã?
136 * ただしã?設定情報は、以前ã?状態がそã?ままキープされてã�?�¾すã?
137 *
138 * @og.rev 3.5.4.8 (2004/02/23) paramInit メソãƒ?ƒ‰で、å?期化を行いますã?
139 * @og.rev 3.5.6.1 (2004/06/25) lang è¨?ªžコーãƒ?属æ?を削除しますã?
140 *
141 * @param table DBTableModelオブジェクãƒ?
142 */
143 @Override
144 public void init( final DBTableModel table ) {
145 table2 = table;
146 firstStep = true;
147 }
148
149 /**
150 * å†?®¹をクリア(初期åŒ?しますã?
151 *
152 * @og.rev 3.5.6.3 (2004/07/12) cubeSortType , gokeiSortDir 属æ?を追åŠ?�—ますã?
153 * @og.rev 3.7.0.4 (2005/03/18) noDisplayKeys 属æ?を追åŠ?�—ますã?
154 * @og.rev 3.7.1.1 (2005/05/31) shokeiLabel,gokeiLabel の初期値変更
155 * @og.rev 5.2.2.0 (2010/11/01) columnDisplayKeys、clsAdd、useClassAdd 属æ?を追åŠ?�—まã�?
156 * @og.rev 5.5.5.0 (2012/07/20) useHeaderResource追åŠ?
157 */
158 @Override
159 public void clear() {
160 super.clear();
161 groupByData = null;
162 groupByCls = null;
163 rowClmNo = -1; // ROWカラãƒ??カラãƒ?•ª号
164 colClmNo = -1; // CLMカラãƒ??カラãƒ?•ª号
165 headCount = 0; // HEADカラãƒ??数
166 sumCount = 1; // 合計カラãƒ??数
167 breakClmNo = -1; // ブレークするカラãƒ??カラãƒ?•ª号
168 noGroupClm = null; // グループ化する/しなã�??フラグ配å?
169 table2 = null;
170 firstStep = true;
171 clmKeys = null;
172 clsAdd = null; // 5.2.2.0 (2010/11/01)
173 shokeiLabel = "小è¨?; // 列小計ã?カラãƒ?�«表示するラベルID
174 gokeiLabel = "合è¨?; // 列合計ã?カラãƒ?�«表示するラベルID
175 cubeSortType = "LOAD"; // 3.5.6.3 (2004/07/12)
176 gokeiSortDir = null; // 3.5.6.3 (2004/07/12) 列合計ã?カラãƒ?‚’ソートする方å�?
177 noDisplayKeys = null; // 3.7.0.4 (2005/03/18)
178 columnDisplayKeys = null; // 5.2.2.0 (2010/11/01)
179 firstClmGokei = false; // 5.2.2.0 (2010/11/01)
180 useHeaderColumn = false; // 5.2.2.0 (2010/11/01)
181 useClassAdd = false; // 5.2.2.0 (2010/11/01)
182 useHeaderResource = false; // 5.5.5.0 (2012/07/20)
183 headerCode = null; // 5.5.5.0 (2012/07/28)
184 }
185
186 /**
187 * DBTableModel から HTMLæ–?—å?を作æ?して返しますã?
188 * startNo(表示開始位置)から、pageSize(表示件数)までのViewæ–?—å?を作æ?しますã?
189 * 表示残りãƒ??タã�?pageSize 以下ã?場合ã?,残りのãƒ??タをすべて出力しますã?
190 *
191 * @og.rev 3.5.5.0 (2004/03/12) No æ¬?��のもã?の作æ?判断ロジãƒ?‚¯を追åŠ?
192 * @og.rev 3.5.6.1 (2004/06/25) lang è¨?ªžコーãƒ?属æ?を削除しますã?
193 * @og.rev 3.5.6.4 (2004/07/16) ヘッãƒ??とボディー部をJavaScriptでåˆ?›¢
194 * @og.rev 3.7.0.4 (2005/03/18) setNoDisplay メソãƒ?ƒ‰を追åŠ?
195 * @og.rev 4.3.1.0 (2008/09/08) 編é›?¡Œã?みを表示する属æ?(isSkipNoEdit)追åŠ?
196 * @og.rev 5.0.0.3 (2009/09/22) 合計å?をcubeの先é?に出せるようにする
197 * @og.rev 5.1.0.0 (2009/11/04) ↑で合計å?がè¤?•°カラãƒ?˜在する場合に正しく表示されなã�?ƒ�グを修正
198 * @og.rev 5.2.2.0 (2010/11/01) setColumnDisplay メソãƒ?ƒ‰を追åŠ?
199 *
200 * @param startNo 表示開始位置
201 * @param pageSize 表示件数
202 *
203 * @return DBTableModelから作æ?されã�?HTMLæ–?—å?
204 */
205 @Override
206 public String create( final int startNo, final int pageSize ) {
207 if( firstStep ) {
208 paramInit( table2 );
209 super.init( makeCrossTable(table2) );
210 super.setNoDisplay( noDisplayKeys ) ; // 3.7.0.4 (2005/03/18)
211 super.setColumnDisplay( columnDisplayKeys ) ; // 5.2.2.0 (2010/11/01)
212 markerSet( this ); // 3.5.6.4 (2004/07/16)
213 firstStep = false;
214 }
215
216 if( getRowCount() == 0 ) { return ""; } // 暫定å?置
217
218 int clmCnt = getColumnCount(); // 3.5.5.7 (2004/05/10)
219
220 headerLine = null;
221
222 int lastNo = getLastNo( startNo, pageSize );
223 int blc = getBackLinkCount();
224 String backData = null;
225
226 StringBuilder out = new StringBuilder( HybsSystem.BUFFER_LARGE );
227
228 out.append( getCountForm( startNo,pageSize ) );
229 out.append( getHeader() );
230
231 String ckboxTD = " <td class=\"" + ViewCrossTableParam.HEADER1 + "\">";
232
233 out.append("<tbody>").append( HybsSystem.CR );
234 int bgClrCnt = 0;
235 boolean shokei;
236 for( int row=startNo; row<lastNo; row++ ) {
237 // if( isSkip( row ) ) { continue; } // 3.5.3.1 (2003/10/31)
238 if( isSkip( row ) || isSkipNoEdit( row ) ) { continue; } // 4.3.1.0 (2008/09/08)
239 // キーブレイク時ã?ヘッãƒ??設å®?
240 if( breakClmNo >= 0 ) {
241 String val = getValue( row,breakClmNo );
242 if( backData == null ) { // キーブレイクの初期ãƒ??タ設定ã?
243 backData = val;
244 }
245 else {
246 if( ! backData.equals( val ) ) {
247 backData = val;
248 out.append( getHeadLine() );
249 }
250 }
251 }
252 // 小計ã?ãƒ?ƒ€ー時ã?クラス設å®?
253 String val2 = getValue( row,rowClmNo );
254 if( val2.length() == 0 ) {
255 shokei = true;
256 out.append("<tr class=\"").append( ViewCrossTableParam.SHOKEI ).append("\">");
257 }
258 else {
259 shokei = false;
260 out.append("<tr").append( getBgColorCycleClass( bgClrCnt++ ) ).append(">");
261 }
262 out.append( HybsSystem.CR );
263 // 3.5.5.0 (2004/03/12) No æ¬?��のもã?の作æ?判断追åŠ?
264 if( isNumberDisplay() ) {
265 out.append( makeCheckbox( ckboxTD, row, blc ) ).append( HybsSystem.CR );
266 }
267 for(int column = 0; column < clmCnt; column++) {
268 if( isColumnDisplay( column ) ) {
269 if( column < headCount-1 ) { // CUBEではなã�?¡Œã?ãƒ?ƒ€ー部
270 String val = getGroupData( column,getRendererValue(row,column) );
271 out.append(" <td class=\"").append( groupByCls[column] ).append("\">");
272 out.append( val );
273 }
274 else if( column == headCount-1 ) { // ヘッãƒ??のæœ?¾Œ尾
275 if( shokei ) {
276 out.append(" <td class=\"").append( ViewCrossTableParam.SHOKEI ).append("\">");
277 out.append( shokeiLabel );
278 }
279 else {
280 if( breakClmNo > 0 ) { // ヘッãƒ??があるå?å�?
281 out.append(" <td class=\"").append( groupByCls[column-1] ).append("\">");
282 }
283 else {
284 out.append(" <td class=\"").append( ViewCrossTableParam.HEADER1 ).append("\">");
285 }
286 out.append( getRendererValue(row,column) );
287 }
288 }
289 // else if( column >= clmCnt-sumCount ) { // CUBEのæœ?µ‚カラãƒ?列合è¨?
290 else if( column >= clmCnt-sumCount && ! firstClmGokei ) { // 5.0.0.3 (2009/09/22) CUBEのæœ?µ‚カラãƒ?列合è¨?
291 out.append(" <td class=\"").append( ViewCrossTableParam.SHOKEI ).append("\">");
292 out.append( getRendererValue(row,column) );
293 }
294 // else if( column == headCount && firstClmGokei ) { // 5.0.0.3 (2009/09/22) CUBEの先é?カラãƒ?列合è¨?
295 else if( column >= headCount && column < headCount + sumCount && firstClmGokei ) { // 5.1.0.0 (2009/11/04)
296 out.append(" <td class=\"").append( ViewCrossTableParam.SHOKEI ).append("\">");
297 // out.append( getRendererValue(row,clmCnt-sumCount) );
298 out.append( getRendererValue(row,clmCnt-sumCount+(column-headCount)) ); // 5.1.0.0 (2009/11/04)
299 }
300 else { // カラãƒ?SUMåˆ?
301 if( useClassAdd && clsAdd[column] != null ) {
302 out.append(" <td class=\"").append( clsAdd[column] ).append("\">");
303 }
304 else {
305 out.append(" <td>");
306 }
307 if( firstClmGokei ){
308 // out.append( getRendererValue(row,column-1) ); // 合計行を先é?に出すと1つずれã‚?
309 out.append( getRendererValue(row,column-sumCount) ); // 5.1.0.0 (2009/11/04)
310 }
311 else{
312 out.append( getRendererValue(row,column) );
313 }
314 }
315 out.append("</td>").append( HybsSystem.CR );
316 }
317 }
318 out.append("</tr>").append( HybsSystem.CR );
319 }
320 out.append("</tbody>").append( HybsSystem.CR );
321 out.append("</table>").append( HybsSystem.CR );
322
323 out.append( getScrollBarEndDiv() ); // 3.8.0.3 (2005/07/15)
324 return out.toString();
325 }
326
327 /**
328 * パラメータå†?®¹をå?期化しますã?
329 *
330 * @og.rev 3.5.4.8 (2004/02/23) 新規作æ?
331 * @og.rev 3.5.6.3 (2004/07/12) 列ã?ãƒ?ƒ€ーのソート方法をæŒ?®?
332 * @og.rev 5.0.0.3 (2009/09/22) 合計行をCUBEの先é?に持ってくるためのフラグ追åŠ?
333 * @og.rev 5.2.2.0 (2010/11/01) useHeaderColumn,useClassAdd 属æ?の追åŠ?
334 *
335 * @param table 入力もとの DBTableModelオブジェクãƒ?
336 */
337 private void paramInit( final DBTableModel table ) {
338 String breakColumn = getParam( ViewCrossTableParam.BREAK_COLUMN_KEY , null );
339 String noGroupColumns = getParam( ViewCrossTableParam.NO_GROUP_COLUMNS_KEY , null );
340 String sumNumber = getParam( ViewCrossTableParam.SUM_NUMBER_KEY , null );
341 shokeiLabel = getParam( ViewCrossTableParam.SHOKEI_LABEL_KEY , shokeiLabel );
342 gokeiLabel = getParam( ViewCrossTableParam.GOKEI_LABEL_KEY , gokeiLabel );
343 String cubeXColumn = getParam( ViewCrossTableParam.CUBE_X_COLUMN_KEY , null ); // CUBE計算ã??‘つ目(X)カラãƒ?‚’æŒ?®?
344 String cubeYColumn = getParam( ViewCrossTableParam.CUBE_Y_COLUMN_KEY , null ); // CUBE計算ã??’つ目(Y)カラãƒ?‚’æŒ?®?
345 cubeSortType = getParam( ViewCrossTableParam.CUBE_SORT_TYPE_KEY , "LOAD" ); // 3.5.6.3 (2004/07/12)
346 gokeiSortDir = getParam( ViewCrossTableParam.GOKEI_SORT_DIR_KEY , null ); // 3.5.6.3 (2004/07/12)
347 firstClmGokei = StringUtil.nval( getParam( ViewCrossTableParam.FIRST_CLM_GOKEI_KEY , null ), false); // 5.0.0.3 (2009/09/22)
348 useHeaderColumn = StringUtil.nval( getParam( ViewCrossTableParam.USE_HEADER_COLUMN , null ), false); // 5.2.2.0 (2010/11/01)
349 useClassAdd = StringUtil.nval( getParam( ViewCrossTableParam.USE_CLASS_ADD , null ), false); // 5.2.2.0 (2010/11/01)
350 useHeaderResource = StringUtil.nval( getParam( ViewCrossTableParam.USE_HEADER_RSC , null ), false); // 5.5.5.0 (2012/07/20)
351 headerCode = getParam( ViewCrossTableParam.HEADER_CODE_KEY , null ); // 5.5.5.0 (2012/07/28)
352
353 if( sumNumber != null ) {
354 sumCount = Integer.parseInt( sumNumber );
355 }
356
357 // HEAD数=カラãƒ?•°-SUM数-1(COLåˆ? ROW は、HEADに含みますã?
358 headCount = table.getColumnCount() - sumCount - 1;
359
360 // 3.5.5.9 (2004/06/07)
361 if( cubeXColumn != null ) {
362 rowClmNo = table.getColumnNo( cubeXColumn );
363 }
364 else {
365 rowClmNo = headCount-1; // ROWカラãƒ??カラãƒ?•ª号
366 }
367
368 // 3.5.5.9 (2004/06/07)
369 if( cubeYColumn != null ) {
370 colClmNo = table.getColumnNo( cubeYColumn );
371 }
372 else {
373 colClmNo = headCount; // CLMカラãƒ??カラãƒ?•ª号
374 }
375
376 if( breakColumn != null ) {
377 breakClmNo = table.getColumnNo( breakColumn );
378 }
379
380 groupByData = new String[headCount];
381 groupByCls = new String[headCount];
382 Arrays.fill( groupByCls,ViewCrossTableParam.HEADER2 ); // 変であるがã?æœ??に入れ替えが発生する為ã€?
383
384 noGroupClm = new boolean[headCount]; // グループ化する/しなã�??フラグ配å?
385 Arrays.fill( noGroupClm,false );
386
387 if( noGroupColumns != null ) {
388 String[] gClms = StringUtil.csv2Array( noGroupColumns );
389 for( int i=0; i<gClms.length; i++ ) {
390 noGroupClm[table.getColumnNo( gClms[i] )] = true;
391 }
392 }
393
394 if( ! "true".equalsIgnoreCase( gokeiSortDir ) &&
395 ! "false".equalsIgnoreCase( gokeiSortDir ) ) {
396 gokeiSortDir = null;
397 }
398 }
399
400 /**
401 * CUBEではなã�?¡Œã?ãƒ?ƒ€ー部の値が前と同じならã?、ゼロæ–?—å?を返しますã?
402 *
403 * @param clm カラãƒ?•ª号
404 * @param val 比è¼?�™るå?
405 *
406 * @return 前と同じなã‚?""をã?異なるå?合ã?、引数の val を返しますã?
407 */
408 private String getGroupData( final int clm,final String val ) {
409 if( noGroupClm[clm] ) { return val; }
410
411 if( val.equals( groupByData[clm] )) {
412 return "";
413 }
414 else {
415 groupByData[clm] = val;
416 groupByCls[clm] = ( groupByCls[clm].equals( ViewCrossTableParam.HEADER1 )) ? ViewCrossTableParam.HEADER2 : ViewCrossTableParam.HEADER1 ;
417 return val;
418 }
419 }
420
421 /**
422 * 選択用のチェãƒ?‚¯ボックスと行番号と変更タイãƒ?A,C,D)を表示しますã?
423 *
424 * @param ckboxTD チェãƒ?‚¯ボックスのタグ(マルチカラãƒ?™‚のrowspan対å¿?
425 * @param row 行番号
426 * @param blc バックラインカウンãƒ?先é?へ戻るリンク間隔)
427 *
428 * @return tdタグで囲まれたチェãƒ?‚¯ボックスのHTMLæ–?—å?
429 */
430 @Override
431 protected String makeCheckbox( final String ckboxTD,final int row,final int blc ) {
432 StringBuilder out = new StringBuilder( HybsSystem.BUFFER_MIDDLE );
433
434 out.append( ckboxTD ).append("</td>");
435 out.append( ckboxTD ).append("</td>");
436 out.append( ckboxTD );
437 // 3.5.1.0 (2003/10/03) Noカラãƒ?�«、numberType 属æ?を追åŠ?
438 if( blc != 0 && (row+1) % blc == 0 ) {
439 out.append( "<a href=\"#top\">" ).append( (row+1) ).append( "</a>" );
440 } else {
441 out.append( (row+1) );
442 }
443 out.append("</td>");
444
445 return out.toString();
446 }
447
448 /**
449 * ヘッãƒ??繰り返し部をã?getTableHead()メソãƒ?ƒ‰からåˆ?›¢ã€?
450 *
451 * @og.rev 3.5.4.5 (2004/01/23) 実è£?‚’getHeadLine( String thTag )に移å‹?
452 * @og.rev 3.5.5.0 (2004/03/12) No æ¬?��のもã?の作æ?判断ロジãƒ?‚¯を追åŠ?
453 * @og.rev 5.0.0.3 (2009/09/17) 合計行を出力する位置をfirstClmGokeiで変えã‚?
454 * @og.rev 5.2.2.0 (2010/11/01) é›?¨ˆ部の ColumnDisplay/NoDisplay 対å¿?
455 * @og.rev 5.5.5.0 (2012/07/28) useHeaderResource利用時ã?ヘッãƒ??ラベル/コードリソース対å¿?
456 * @og.rev 5.7.4.2 (2014/03/20) ヘッãƒ??のリソース適用見直ã�?
457 * @og.rev 5.7.4.3 (2014/03/28) useHeaderResource 単独でリソース適用しますã?
458 *
459 * @return ãƒ??ブルのタグæ–?—å?
460 */
461 @Override
462 protected String getHeadLine() {
463 if( headerLine != null ) { return headerLine; } // キャãƒ?‚·ュを返すã€?
464
465 String rowspan = "";
466 if( sumCount > 1 ) { rowspan = " rowspan=\"2\""; }
467
468 String thTag = "<th" + rowspan;
469
470 StringBuilder buf = new StringBuilder( HybsSystem.BUFFER_MIDDLE );
471
472 buf.append("<tr").append( rowspan ).append(" class=\"row_h\"").append(" >").append( HybsSystem.CR );
473
474 // 3.5.5.0 (2004/03/12) No æ¬?��のもã?の作æ?判断追åŠ?
475 if( isNumberDisplay() ) {
476 buf.append( thTag ).append(" colspan='3'>").append( getNumberHeader() ).append("</th>");
477 }
478
479 buf.append( HybsSystem.CR );
480 // ヘッãƒ??部åˆ??、そのまま表示しますã?
481 for(int column = 0; column < headCount; column++) {
482 if( isColumnDisplay( column ) ) {
483 buf.append( thTag ).append(">");
484 buf.append( getColumnLabel(column) );
485 buf.append("</th>").append( HybsSystem.CR );
486 }
487 }
488
489 // ヘッãƒ??部åˆ?上段)は、カラãƒ??列を利用しますã?
490 String colspan = "";
491 if( sumCount > 1 ) { colspan = " colspan='" + sumCount + "'"; }
492
493 // 5.2.2.0 (2010/11/01) é›?¨ˆ部の ColumnDisplay/NoDisplay 対å¿?
494 // String gokeiClm = "<th" + colspan + ">" + temp + "</th>" + HybsSystem.CR ;
495 String gokeiClm = null;
496 if( isColumnDisplay( headCount+(clmKeys.length-1)*sumCount ) ) {
497 String temp = clmKeys[clmKeys.length-1];
498 if( temp == null || temp.length() == 0 ) {
499 temp = gokeiLabel;
500 }
501
502 gokeiClm = "<th" + colspan + ">" + temp + "</th>" + HybsSystem.CR ;
503 }
504
505 // 5.2.2.0 (2010/11/01) æœ?¾Œã?カラãƒ?�Œ、合計行ã?
506 // 5.0.0.3 (2009/09/22) firstClmGokei ã�?trueの場合ã?cubeの先é?に出すよã�?�«しますã?
507 // if( firstClmGokei && isColumnDisplay( headCount+clmKeys.length-1 ) ) {
508 if( firstClmGokei && gokeiClm != null ) {
509 buf.append( gokeiClm );
510 }
511
512 // // 5.0.0.3 (2009/09/22) trueの場合ã?cubeの先é?に出すよã�?�«しますã?
513 // if( firstClmGokei ){
514 // String temp = clmKeys[clmKeys.length-1];
515 // if( temp == null || temp.length() == 0 ) {
516 // temp = gokeiLabel;
517 // }
518 // buf.append( "<th").append( colspan ).append( ">" );
519 // buf.append( temp );
520 // buf.append("</th>").append( HybsSystem.CR );
521 // }
522
523 // 3.7.0.4 (2005/03/18) カラãƒ??列ã?、カラãƒ?•ª号と別物
524 ResourceManager resource = getResourceManager();
525 Selection selection = null;
526 if( headerCode != null && headerCode.length() > 0 && resource != null ){
527 DBColumn clmTmp = resource.getDBColumn( headerCode );
528 //selection = new Selection_CODE(resource.getCodeData( headerCode )); code直の場å�?
529 if ( clmTmp != null ){
530 selection = clmTmp.getSelection();
531 }
532 }
533
534 // 5.7.4.2 (2014/03/20) ヘッãƒ??のリソース適用見直ã�?
535 // 5.7.4.3 (2014/03/28) useHeaderResource 単独でリソース適用しますã?
536 DBColumn colClm = null;
537 // if( useHeaderResource && useHeaderColumn ) {
538 if( useHeaderResource ) {
539 colClm = table2.getDBColumn( colClmNo );
540 }
541
542 for( int keyNo = 0; keyNo < clmKeys.length-1; keyNo++ ) {
543 // 5.2.2.0 (2010/11/01) ColumnDisplay/NoDisplay 対å¿?
544 if( isColumnDisplay( headCount+keyNo ) ) {
545 buf.append( "<th").append( colspan ).append( ">" );
546 // if( headerCode != null && headerCode.length() > 0 && selection != null ){
547 if( selection != null ){
548 buf.append( selection.getValueLabel( clmKeys[keyNo] ) );
549 }
550 // 5.7.4.2 (2014/03/20) ヘッãƒ??のリソース適用見直ã�?
551 // else if( useHeaderResource && useHeaderColumn ){ // 5.5.5.0 (2012/07/28) ヘッãƒ??リソース対å¿?
552 // buf.append( getColumnLabel(headCount+keyNo) );
553 // }
554 // 5.7.4.3 (2014/03/28) ヘッãƒ??のリソース適用は、CLMカラãƒ??カラãƒ?•ª号のみとしますã?
555 else if( colClm != null ) {
556 buf.append( colClm.getRendererValue( clmKeys[keyNo] ) );
557 }
558 else{
559 buf.append( clmKeys[keyNo] );
560 }
561 buf.append("</th>").append( HybsSystem.CR );
562 }
563 }
564
565 // 5.2.2.0 (2010/11/01) æœ?¾Œã?カラãƒ?�Œ、合計行ã?
566 // 5.0.0.3 (2009/09/22) firstClmGokei ã�?trueの場合ã?cubeの先é?に出すよã�?�«しますã?
567 // if( ! firstClmGokei && isColumnDisplay( headCount+clmKeys.length-1 ) ) {
568 if( ! firstClmGokei && gokeiClm != null ) {
569 buf.append( gokeiClm );
570 }
571
572 // 3.5.6.2 (2004/07/05) makeCrossTable( DBTableModel table ) に移å‹?
573 // æœ?µ‚カラãƒ?åˆ?がNULL(空æ–?—å?)の場合ã?列合計ですã?
574 // if( ! firstClmGokei ){ // 5.0.0.3 (2009/09/22) falseの場合ã?æœ?µ‚å?に出ã�?
575 // String temp = clmKeys[clmKeys.length-1];
576 // if( temp == null || temp.length() == 0 ) {
577 // temp = gokeiLabel;
578 // }
579 // buf.append( "<th").append( colspan ).append( ">" );
580 // buf.append( temp );
581 // buf.append("</th>").append( HybsSystem.CR );
582 // }
583
584 buf.append("</tr>").append( HybsSystem.CR );
585
586 if( sumCount > 1 ) {
587 buf.append("<tr").append(" class=\"row_h\"").append(" >").append( HybsSystem.CR );
588 int clmCnt = getColumnCount(); // 3.5.5.7 (2004/05/10)
589 for(int column = headCount; column < clmCnt; column++) {
590 if( isColumnDisplay( column ) ) {
591 buf.append( "<th>");
592 buf.append( getColumnLabel(column) );
593 buf.append("</th>").append( HybsSystem.CR );
594 }
595 }
596 buf.append("</tr>").append( HybsSystem.CR );
597 }
598
599 headerLine = buf.toString();
600 return headerLine;
601 }
602
603 /**
604 * クロスé›?¨ˆ結果の DBTableModelオブジェクトを作æ?しますã?
605 *
606 * @og.rev 3.5.4.8 (2004/02/23) paramInit メソãƒ?ƒ‰で、å?期化を行いますã?
607 * @og.rev 3.5.6.3 (2004/07/12) 列ã?ãƒ?ƒ€ーのソート可否のæŒ?®šを追åŠ?
608 * @og.rev 4.0.0.0 (2007/11/27) ヘッãƒ??カラãƒ??エãƒ?‚£ター、レンãƒ?ƒ©ー適用対å¿?
609 * @og.rev 4.3.5.7 (2008/03/22) ↑リソースが存在しなã�??合ã?、ラベルのみ入れ替ã�?
610 * @og.rev 5.2.2.0 (2010/11/01) useHeaderColumn,useClassAdd 属æ?の追åŠ?
611 * @og.rev 5.7.4.3 (2014/03/28) useHeaderColumn の適用条件をã?æœ??のé›?¨ˆカラãƒ??みに変更ã€?
612 *
613 * @param table 入力もとの DBTableModelオブジェクãƒ?
614 *
615 * @return DBTableModelオブジェクãƒ?
616 */
617 private DBTableModel makeCrossTable( final DBTableModel table ) {
618 Set<String> clmData = gatSortAlgorithmSet();
619
620 // 列ã?キーとなるカラãƒ??値を取得しますã?
621 int rowCnt = table.getRowCount(); // 3.5.5.7 (2004/05/10)
622 for( int row=0; row<rowCnt; row++ ) {
623 String clm = table.getValue( row,colClmNo );
624 if( clm.length() > 0 ) { clmData.add( clm ); }
625 }
626 // ゼロストリングは、合計行になりますã?で、最後に追åŠ?�—ますã?
627
628 // 3.5.6.3 (2004/07/12) ゼロストリングは、合計行になりますã?で、最後に追åŠ?�—ますã?
629 // clmKeys = new String[ clmData.size() + 1 ];
630 // clmKeys = clmData.toArray( clmKeys ) ;
631 clmKeys = clmData.toArray( new String[clmData.size() + 1] ) ;
632
633 clmKeys[clmKeys.length-1] = "" ;
634
635 int numberOfColumns = headCount + clmKeys.length * sumCount ;
636
637 DBTableModel tableImpl = DBTableModelUtil.newDBTable();
638 tableImpl.init( numberOfColumns );
639
640 // ヘッãƒ??カラãƒ?ROWãƒ??タ含ã‚?は、そのまま、設定しますã?
641 for(int column=0; column<headCount; column++) {
642 tableImpl.setDBColumn( column,table.getDBColumn(column) );
643 }
644
645 // 列情報は、合計å?のカラãƒ?®š義を使用しますã?
646 DBColumn[] dbColumn = new DBColumn[sumCount];
647 for( int i=0; i<sumCount; i++ ) {
648 dbColumn[i] = table.getDBColumn(headCount + 1 + i);
649 }
650
651 // 列情報は、å?の名前をカラãƒ??値に変えて、合計カラãƒ??のコピã?æƒ??を設定しますã?
652
653 int sumId = 0;
654 ResourceManager resource = getResourceManager();
655 useHeaderColumn = useHeaderColumn && resource != null ; // 5.2.2.0 (2010/11/01)
656
657 // 5.2.2.0 (2010/11/01) useClassAdd 属æ?の追åŠ?
658
659 clsAdd = new String[numberOfColumns];
660
661 // 列情報カラãƒ??、ã?ãƒ?ƒ€ーåˆ?�«割り当てられる為ã€?–‹始が、headCount からになりますã?
662 for(int column=headCount; column<numberOfColumns; column++) {
663 DBColumn dbClm = dbColumn[sumId];
664 String clmKey = clmKeys[ (column-headCount)/sumCount ];
665
666 // 5.2.2.0 (2010/11/01) useClassAdd 属æ?の追åŠ?
667 if( useClassAdd ) {
668 // ※ 特殊対応:cssなどでæŒ?®šできるIDやCLASS属æ?は、å?頭æ–?—が数字ã?場合ã?ã€?
669 // 無効になりますã?(つまりã?効きませんã€?
670 // 表示ヘッãƒ??は、年月や、社員番号(数å?などのケースもありますã?そこで、å?頭が数字ã?
671 // 場合ã?ã€?x"(小文字ã?x)をè?動的に頭に追åŠ?�—ますã?
672 StringBuilder buf = new StringBuilder();
673 if( clmKey != null && clmKey.length() > 0 ) {
674 char ch = clmKey.charAt(0);
675 if( ch >= '0' && ch <= '9' ) {
676 buf.append( "x" );
677 }
678 buf.append( clmKey );
679 }
680
681 String nm = dbClm.getName();
682 if( nm != null && nm.length() > 0 ) {
683 buf.append( " " );
684 char ch = nm.charAt(0);
685 if( ch >= '0' && ch <= '9' ) {
686 buf.append( "x" );
687 }
688 buf.append( nm );
689 }
690 clsAdd[column] = buf.toString();
691 }
692
693 // 4.0.0.0 (2007/11/27)
694 // if( resource != null && "true".equalsIgnoreCase( getParam( "useHeaderColumn", null ) ) ) {
695 // 5.2.2.0 (2010/11/01) 処ç�?¦‹直しã?useHeaderColumn の前å?しと、setName 対å¿?
696
697 // 5.7.4.3 (2014/03/28) useHeaderColumn の適用条件をã?æœ??のé›?¨ˆカラãƒ??みに変更ã€?
698 // if( useHeaderColumn ) {
699 if( useHeaderColumn && sumId == 0 ) {
700 // String clmKey = clmKeys[ (column-headCount)/sumCount ]; // 5.2.2.0 (2010/11/01) 上に移å‹?
701 DBColumn clmTmp = resource.getDBColumn( clmKey );
702 if( clmTmp == null ) {
703 // tableImpl.setDBColumn( column,dbColumn[sumId] ); }
704 DBColumnConfig dbCfg2 = dbClm.getConfig();
705 if( clmKey != null && clmKey.length() > 0 ) { // 5.2.2.0 (2010/11/01)
706 dbCfg2.setName( clmKey );
707 dbCfg2.setLabelData( resource.getLabelData( clmKey ) );
708 }
709 else {
710 dbCfg2.setLabelData( resource.getLabelData( gokeiLabel ) );
711 }
712 dbClm = new DBColumn( dbCfg2 );
713 // tableImpl.setDBColumn( column, new DBColumn( dbCfg2 ) );
714 }
715 else {
716 // tableImpl.setDBColumn( column,dbClm );
717 dbClm = clmTmp;
718 }
719 }
720 // else {
721 // tableImpl.setDBColumn( column,dbColumn[sumId] );
722 // }
723
724 tableImpl.setDBColumn( column,dbClm );
725
726 sumId++;
727 if( sumId % sumCount == 0 ) {
728 sumId = 0;
729 }
730 }
731
732 // クロスé›?¨ˆデータの作æ?
733 CrossMap cross = new CrossMap( clmKeys,headCount,sumCount );
734 for( int row=0; row<rowCnt; row++ ) {
735 String[] data = table.getValues( row );
736 cross.add( data );
737 }
738
739 // ãƒ??タ部の設å®?
740 int size = cross.getSize();
741 for( int row=0; row<size; row++ ) {
742 tableImpl.addValues( cross.get( row ), row );
743 }
744
745 tableImpl.resetModify();
746
747 final DBTableModel model ;
748 if( gokeiSortDir != null ) {
749 DBTableModelSorter temp = new DBTableModelSorter();
750 temp.setModel( tableImpl );
751
752 boolean direction = Boolean.valueOf( gokeiSortDir ).booleanValue();
753 temp.sortByColumn( numberOfColumns-1,direction );
754 model = temp ;
755 }
756 else {
757 model = tableImpl;
758 }
759 return model ;
760 }
761
762 /**
763 * 列ã?ãƒ?ƒ€ーのソート方法に応じたã?Setオブジェクトを返しますã?
764 * ここでは、NUMBER , STRING , LOAD の?“種類用意してã�?�¾すã?
765 *
766 * @og.rev 3.5.6.3 (2004/07/12) 新規作æ?
767 *
768 * @return ソート方法に応じたSetオブジェクãƒ?
769 */
770 private Set<String> gatSortAlgorithmSet() {
771 final Set<String> rtnSet ;
772
773 if( "LOAD".equalsIgnoreCase( cubeSortType ) ) {
774 rtnSet = new LinkedHashSet<String>();
775 }
776 else if( "NUMBER".equalsIgnoreCase( cubeSortType ) ) {
777 rtnSet = new TreeSet<String>( numberSort );
778 }
779 else if( "STRING".equalsIgnoreCase( cubeSortType ) ) {
780 rtnSet = new TreeSet<String>();
781 }
782 else {
783 String errMsg = "cubeSortType は、NUMBER,STRING,LOAD 以外指定できませんã€? +
784 " cubeSortType=[" + cubeSortType + "]";
785 throw new HybsSystemException( errMsg );
786 }
787
788 return rtnSet ;
789 }
790
791 /**
792 * 表示不可カラãƒ?��をã?カンマ区åˆ?‚Šで与えますã?
793 * 例ï¼?OYA,KO,HJO,SU,DYSET,DYUPD"
794 * null を与えたå?合ã?,なにもしませんã€?
795 *
796 * 注意:このクラスでは、DBTableModel を作り直すタイミングがã?
797 * create メソãƒ?ƒ‰実行時ですã?(パラメータの初期化がå¿?¦�な為)
798 * よって、このメソãƒ?ƒ‰は、å?期が終äº?¾Œに、å?セãƒ?ƒˆしますã?
799 *
800 * @og.rev 3.7.0.4 (2005/03/18) 新規作æ?
801 *
802 * @param columnName カラãƒ?��
803 */
804 @Override
805 public void setNoDisplay( final String columnName ) {
806 noDisplayKeys = columnName;
807 }
808
809 /**
810 * 表示可能カラãƒ?��をã?カンマ区åˆ?‚Šで与えますã?
811 * 例ï¼?OYA,KO,HJO,SU,DYSET,DYUPD"
812 * setColumnDisplay( int column,boolean rw ) の簡易版ですã?
813 * null を与えたå?合ã?,なにもしませんã€?
814 * またã?全カラãƒ?�«つã�?�¦、有効にする場合ã?、columnName="*" を設定しますã?
815 *
816 * @og.rev 5.2.2.0 (2010/11/01) 新規追åŠ?
817 *
818 * @param columnName カラãƒ?��
819 */
820 @Override
821 public void setColumnDisplay( final String columnName ) {
822 columnDisplayKeys = columnName;
823 }
824
825 /**
826 * NUMBER ソート機è?(整数限å®? å†?ƒ¨クラス
827 * これは通常のソートではなくã?ヘッãƒ??に使ã�?ƒ©ベルのソートなのでã€?
828 * 整数のみと限定しますã?実数の場合ã?、桁合わせ(小数点以下ã?桁数)
829 * されてã�?‚‹とã�?�†前提ですã?
830 *
831 * @og.rev 3.5.6.3 (2004/07/12) 新規作æ?
832 *
833 */
834 private static final Comparator<String> numberSort = new NumberComparator();
835
836 private static class NumberComparator implements Comparator<String>,Serializable {
837 private static final long serialVersionUID = 4000 ; // 4.0.0 (2005/01/31)
838
839 public int compare( final String s1, final String s2 ) {
840 if( s1.length() > s2.length() ) { return 1; }
841 else if( s1.length() < s2.length() ) { return -1; }
842 else {
843 return s1.compareTo( s2 );
844 }
845 }
846 }
847
848 /**
849 * 表示é ?›®の編é›?並び替ã�?が可能かどã�?�‹を返しまã�?
850 *
851 * @og.rev 5.1.6.0 (2010/05/01) 新規追åŠ?
852 *
853 * @return 表示é ?›®の編é›?並び替ã�?が可能かどã�?�‹(false:不可能)
854 */
855 @Override
856 public boolean isEditable() {
857 return false;
858 }
859 }