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 org.opengion.hayabusa.common.HybsSystem;
019 import org.opengion.hayabusa.common.HybsSystemException;
020 import org.opengion.fukurou.util.StringUtil;
021 import org.opengion.hayabusa.db.DBTableModel;
022 import org.opengion.hayabusa.html.TableFormatter;
023 import org.opengion.hayabusa.html.ViewGanttTableParam;
024
025 import java.util.regex.Pattern;
026 import java.util.regex.Matcher;
027
028 import java.util.Locale;
029 import java.util.TreeSet;
030 import java.util.List;
031 import java.util.Date;
032 import java.util.Calendar;
033 import java.text.SimpleDateFormat;
034 import java.text.ParseException;
035
036 /**
037 * ガントチャー???ブル形?を作?する、ガントチャート表示クラスです?
038 *
039 * AbstractViewForm により、setter/getterメソ?の?ォルト実?提供して?す?
040 * 各HTMLのタグに?な setter/getterメソ?のみ?追?義して?す?
041 *
042 * AbstractViewForm を継承して?為,ロケールに応じたラベルを?力させる事が出来ます?
043 *
044 * @og.group 画面表示
045 *
046 * @version 4.0
047 * @author Kazuhiko Hasegawa
048 * @since JDK5.0,
049 */
050 public class ViewForm_HTMLGanttTable extends ViewForm_HTMLTable {
051 //* こ?プログラ??VERSION??を設定します? {@value} */
052 private static final String VERSION = "5.5.4.4 (2012/07/20)" ;
053
054 // 3.5.4.0 (2003/11/25) TableFormatter クラス追?
055 private TableFormatter headerFormat = null;
056 private TableFormatter[] bodyFormats = null;
057 private TableFormatter footerFormat = null;
058 private int bodyFormatsCount = 0;
059
060 // 繰り返すTD用 3.5.6.0 (2004/06/18) ?
061 private TableFormatter[] itdFormats = null; // 追?
062
063 private String ganttHeadLine = null;
064 private int[] groupCols = null;
065 private int posDuration = -1;
066 private int posDystart = -1;
067
068 private String formatDystart = ViewGanttTableParam.DYSTART_FORMAT_VALUE;
069 private double minDuration = StringUtil.parseDouble( ViewGanttTableParam.MIN_DURATION_VALUE ) ; // 3.5.5.8 (2004/05/20)
070 private double headerDuration = minDuration ; // 3.5.5.8 (2004/05/20)
071
072 // 3.5.4.6 (2004/01/30) 初期値変更
073 private static final int BODYFORMAT_MAX_COUNT = 10;
074
075 // <(td|th)(.*)>(.*)</(td|th)>を確認す?
076 private static final Pattern cpTdTh =
077 Pattern.compile("\\<(td|th)([^\\>]*)\\>(.*)\\</(td|th)\\>"
078 , Pattern.DOTALL + Pattern.CASE_INSENSITIVE);
079 // 3.5.5.9 (2004/06/07)
080 private int maxDayCnt = 0;
081 private String headerLocale = null;
082 private String[] headDays = null;
083 private int headDaysCnt = 0;
084
085 // 3.5.6.3 (2004/07/12) 行チェ?による編?の hidden
086 private static final String CHECK_ROW =
087 "<input type=\"hidden\" name=\"" + HybsSystem.ROW_SEL_KEY + "\" value=\"";
088
089 // 3.6.1.0 (2005/01/05) 開始日付けと終?付けの??
090 private boolean useSeqDay = false;
091 private String startDay = null;
092 private String endDay = null;
093
094 private boolean useItd = false; // 5.0.0.3 (2009/09/22)
095
096 // 4.3.4.4 (2009/01/01)
097 // /**
098 // * ?ォルトコンストラクター
099 // *
100 // */
101 // public ViewForm_HTMLGanttTable() {
102 // super();
103 // }
104
105 /**
106 * ?をクリア(初期?します?
107 *
108 * @og.rev 3.1.1.0 (2003/03/28) 同期メソ?(synchronized付き)を非同期に変更する?
109 * @og.rev 3.5.0.0 (2003/09/17) Noカラ?、表示を?て消せるよ?、class 属?を追??
110 * @og.rev 3.5.4.0 (2003/11/25) TableFormatter クラスを使用するように変更?
111 * @og.rev 3.5.5.8 (2004/05/20) minDuration , headerDuration 追?? 不要な変数削除
112 * @og.rev 3.5.6.0 (2004/06/18) ithFormat , itdFormat 属?削除、itdFormats属?を追?
113 * @og.rev 3.6.1.0 (2005/01/05) startDay,endDay,useSeqDay 属?追?
114 * @og.rev 5.0.0.3 (2009/09/22) itdタグの有無でcolspan対策?tdの出力?数を調整
115 */
116 @Override
117 public void clear() {
118 super.clear();
119
120 headerFormat = null;
121 bodyFormats = null;
122 footerFormat = null;
123 bodyFormatsCount = 0;
124
125 ganttHeadLine = null;
126 itdFormats = null; // 3.5.6.0 (2004/06/18)
127 groupCols = null;
128 posDuration = -1 ;
129 posDystart = -1;
130 formatDystart = ViewGanttTableParam.DYSTART_FORMAT_VALUE;
131 minDuration = StringUtil.parseDouble( ViewGanttTableParam.MIN_DURATION_VALUE ) ; // 3.5.5.8 (2004/05/20)
132 headerDuration = minDuration ; // 3.5.5.8 (2004/05/20)
133
134 maxDayCnt = 0; // 3.5.5.9 (2004/06/07)
135 headerLocale = null; // 3.5.5.9 (2004/06/07)
136 headDays = null; // 3.5.5.9 (2004/06/07)
137 headDaysCnt = 0; // 3.5.5.9 (2004/06/07)
138
139 useSeqDay = false; // 3.6.1.0 (2005/01/05)
140 startDay = null; // 3.6.1.0 (2005/01/05)
141 endDay = null; // 3.6.1.0 (2005/01/05)
142
143 useItd = false; // 5.0.0.3 (2009/09/22)
144 }
145
146 /**
147 * DBTableModel から HTML??を作?して返します?
148 * startNo(表示開始位置)から、pageSize(表示件数)までのView??を作?します?
149 * 表示残り??タ?pageSize 以下?場合?,残りの??タをすべて出力します?
150 *
151 * @og.rev 3.5.0.0 (2003/09/17) BODY要?? noClass 属?を追??
152 * @og.rev 3.5.0.0 (2003/09/17) <tr>属?は、?のフォーマット?まま使用します?
153 * @og.rev 3.5.2.0 (2003/10/20) ヘッ??繰り返し属?( headerSkipCount )を採用
154 * @og.rev 3.5.3.1 (2003/10/31) skip属?を採用。headerLine のキャ?ュクリア
155 * @og.rev 3.5.4.0 (2003/11/25) TableFormatter クラスを使用するように変更?
156 * @og.rev 3.5.5.0 (2004/03/12) systemFormat(例:[KEY.カラ?]形式?の対?
157 * @og.rev 3.5.5.9 (2004/06/07) IEの colspan が上手く動かな?策?
158 * @og.rev 3.5.5.9 (2004/06/07) [#カラ?] , [$カラ?] に対?
159 * @og.rev 3.5.6.0 (2004/06/18) itdFormat を?BODY毎?Formatを使用するように修正
160 * @og.rev 3.5.6.0 (2004/06/18) '!' 値のみ 追?既存? '$' は、レン?ー
161 * @og.rev 3.5.6.3 (2004/07/12) 行チェ?による編?出来るよ?機?を追?
162 * @og.rev 3.5.6.4 (2004/07/16) ヘッ??とボディー部をJavaScriptで?
163 * @og.rev 3.6.1.0 (2005/01/05) 行チェ?による編?、検索即登録時も可能なようにします?
164 * @og.rev 4.0.0.0 (2005/01/31) 新規作?(getColumnClassName ?getColumnDbType)
165 * @og.rev 3.7.0.1 (2005/01/31) E の colspan バグ対応で入れた?行? 空タグを消す為の修正
166 * @og.rev 4.3.1.0 (2008/09/08) フォーマットが設定されて???合?エラー追?
167 * @og.rev 4.3.7.4 (2009/07/01) tbodyタグの入れ子を解?FireFox対?
168 * @og.rev 5.0.0.3 (2009/09/22) itdタグの有無でcolspan対策?tdの出力?数を調整
169 * @og.rev 5.5.4.4 (2012/07/20) 二重チェ?状態になってしま??
170 *
171 * @param stNo 表示開始位置
172 * @param pgSize 表示件数
173 *
174 * @return DBTableModelから作?され?HTML??
175 */
176 @Override
177 public String create( final int stNo, final int pgSize ) {
178 // ガント?、キーブレイクがあるため?全件表示します?
179 int startNo = 0;
180 int pageSize = getRowCount() ;
181 if( pageSize == 0 ) { return ""; } // 暫定?置
182 boolean outputCheck = true; // 5.5.4.4. (2012/07/20) チェ?ボックス出力判?
183
184 // 4.3.1.0 (2008/09/08)
185 if( headerFormat == null ) {
186 String errMsg = "ViewTagで canUseFormat() = true の場合?Formatter は??です?";
187 throw new HybsSystemException( errMsg );
188 }
189
190 headerLine = null; // 3.5.3.1 (2003/10/31) キャ?ュクリア
191
192 int lastNo = getLastNo( startNo, pageSize );
193 int blc = getBackLinkCount();
194 int hsc = getHeaderSkipCount(); // 3.5.2.0 (2003/10/20)
195 int hscCnt = 1; // 3.5.2.0 (2003/10/20)
196
197 // こ?ビューの特有な属?を?期化
198 paramInit();
199
200 StringBuilder out = new StringBuilder( HybsSystem.BUFFER_LARGE );
201
202 out.append( getCountForm( startNo,pageSize ) );
203
204 if( posDuration < 0 ) { ganttHeadLine = getGanttHeadNoDuration(startNo, lastNo); }
205 else { ganttHeadLine = getGanttHead(startNo, lastNo); }
206
207 out.append( getHeader() );
208
209 if( bodyFormatsCount == 0 ) {
210 bodyFormats[0] = headerFormat ;
211 bodyFormatsCount ++ ;
212 }
213 else {
214 for( int i=0; i<bodyFormatsCount; i++ ) {
215 bodyFormats[i].makeFormat( getDBTableModel() );
216 if( itdFormats[i] != null ) {
217 itdFormats[i].makeFormat( getDBTableModel() );
218 }
219 }
220 }
221 // out.append("<tbody>").append( HybsSystem.CR ); // 4.3.7.4 (2009/07/01)
222
223 String[] astrOldGroupKeys = new String[groupCols.length];
224 for( int nIndex =0; nIndex < astrOldGroupKeys.length; nIndex++) {
225 astrOldGroupKeys[nIndex] = "";
226 }
227
228 StringBuilder bodyBuf = null, itdBuf = null;
229 boolean checked = false; // 3.5.6.3 (2004/07/12)
230 int bgClrCnt = 0;
231 TableFormatter itdFormat = null;
232 for( int row=startNo; row<lastNo; row++ ) {
233 outputCheck = true; // 5.5.4.4. (2012/07/20)
234 // ガントでは、データのスキ??は行いません?
235
236 if(! isSameGroup(row, astrOldGroupKeys)) {
237 // 3.5.6.3 (2004/07/12) キーブレイク時にチェ?行かど?を記録
238 checked = getDBTableModel().isRowChecked( row );
239
240 if( row != startNo ) {
241 // ヘッ??日付けが残って?のに、データがなくなった??
242 while( headDays != null && headDaysCnt < headDays.length ) {
243 itdBuf.append( "<td></td>" );
244 headDaysCnt++;
245 }
246 out.append(StringUtil.replace(bodyBuf.toString(), TableFormatter.HYBS_ITD_MARKER, itdBuf.toString()));
247 itdBuf = null;
248 headDaysCnt = 0;
249 }
250
251 bodyBuf = new StringBuilder( HybsSystem.BUFFER_LARGE );
252
253 // カラ??グループがブレイクするまで、BodyFormatは同?ある前提
254 for( int i=0; i<bodyFormatsCount; i++ ) {
255 TableFormatter bodyFormat = bodyFormats[i];
256 if( ! bodyFormat.isUse( row,getDBTableModel() ) ) { continue; } // 3.5.4.0 (2003/11/25)
257 itdFormat = itdFormats[i]; //
258
259 bodyBuf.append("<tbody").append( getBgColorCycleClass( bgClrCnt++ ) ).append(">");
260 bodyBuf.append( bodyFormat.getTrTag() );
261
262 // 3.5.5.0 (2004/03/12) No ?のも?の作?判断追?
263 if( isNumberDisplay() ) {
264 String ckboxTD = "<td" + bodyFormat.getRowspan() + ">";
265 bodyBuf.append( makeCheckbox( ckboxTD,row,blc ) );
266 outputCheck = false; // 5.5.4.4. (2012/07/20)
267 }
268
269 int cl = 0;
270 for( ; cl < bodyFormat.getLocationSize(); cl++ ) {
271 String fmt = bodyFormat.getFormat(cl);
272 int loc = bodyFormat.getLocation(cl); // 3.5.5.0
273 if( ! bodyFormat.isNoClass() ) {
274 StringBuilder newtg = new StringBuilder( HybsSystem.BUFFER_LARGE );
275 newtg.append("<td class=\"");
276 if( loc >= 0 ) { newtg.append(getColumnDbType(loc)); } // 4.0.0 (2005/01/31)
277 newtg.append("\" ");
278 String tdclass = newtg.toString();
279 fmt = StringUtil.replace( bodyFormat.getFormat(cl) ,"<td", tdclass );
280 }
281 bodyBuf.append( fmt ); // 3.5.0.0
282 // 3.5.5.9 (2004/06/07) #,$ 対?
283 if( loc >= 0 ) {
284 switch( bodyFormat.getType(cl) ) {
285 case '#' : bodyBuf.append( getColumnLabel(loc) ); break;
286 case '$' : bodyBuf.append( getRendererValue(row,loc) ); break;
287 case '!' : bodyBuf.append( getValue(row,loc) ); break;
288 default : bodyBuf.append( getValueLabel(row,loc) ); break;
289 }
290 }
291 else {
292 bodyBuf.append( bodyFormat.getSystemFormat(row,loc) );
293 }
294 }
295 bodyBuf.append( bodyFormat.getFormat(cl) );
296 bodyBuf.append("</tbody>").append( HybsSystem.CR );
297 }
298
299 // 3.5.2.0 (2003/10/20) ヘッ??繰り返し属?( headerSkipCount )を採用
300 if( hsc > 0 && hscCnt % hsc == 0 ) {
301 bodyBuf.append("<tbody class=\"row_h\"").append(" >");
302 bodyBuf.append( getHeadLine() );
303 bodyBuf.append("</tbody>");
304 hscCnt = 1;
305 }
306 else {
307 hscCnt ++ ;
308 }
309 }
310
311 // 3.5.6.3 (2004/07/12) キーブレイク時?チェ?行?状態を繰り返し行に反映
312 // 3.6.1.0 (2005/01/05) さらに、外部でチェ?を?れて?場合?、?別対応する?
313 // if( checked || isChecked( row ) ) {
314 if( (checked || isChecked( row )) && outputCheck ) { // 5.5.4.4. (2012/07/20)
315 getDBTableModel().setRowWritable( row,true );
316 out.append( CHECK_ROW );
317 out.append( row );
318 out.append( "\" />" );
319 }
320
321 itdBuf = formatItd(row, itdFormat, itdBuf);
322 }
323
324 // 残ったデータを??
325 if( null != itdBuf ) {
326 // ヘッ??日付けが残って?のに、データがなくなった??
327 while( headDays != null && headDaysCnt < headDays.length ) {
328 itdBuf.append( "<td></td>" );
329 headDaysCnt++;
330 }
331 out.append(StringUtil.replace(bodyBuf.toString(), TableFormatter.HYBS_ITD_MARKER, itdBuf.toString()));
332 }
333
334 // 3.5.5.9 (2004/06/07) IEの colspan が上手く動かな?策?
335 // minDuration が?1.0 以下?場合?み実?
336 if( minDuration < 1.0d ) {
337 // int tdCount = (int)Math.round( maxDayCnt / minDuration );
338 // 5.0.0.3 (2009/09/22) itdタグの有無でtdCountを変える?
339 int tdCount = useItd ? (int) Math.round( maxDayCnt / minDuration ) : headerFormat.getLocationSize();
340
341 // 3.7.0.1 (2005/01/31) E の colspan バグ対応で入れた?行? 空タグを消す為の修正
342 out.append("<tbody><tr class=\"dummy\">").append( HybsSystem.CR );
343 for( int i=0; i<tdCount; i++ ) {
344 out.append( "<td/>" );
345 }
346 out.append("</tr></tbody>").append( HybsSystem.CR );
347 }
348
349 if( footerFormat != null ) {
350 out.append( getTableFoot() );
351 }
352
353 // out.append("</tbody>").append( HybsSystem.CR ); 4.3.7.4 (2009/07/01)
354 out.append("</table>").append( HybsSystem.CR );
355
356 out.append( getScrollBarEndDiv() ); // 3.8.0.3 (2005/07/15)
357 return out.toString();
358 }
359
360 /**
361 * こ?ビ?に対する特別な初期化を行う?
362 *
363 * @og.rev 3.5.4.0 (2003/11/25) TableFormatter クラスを使用するように変更?
364 * @og.rev 3.5.5.9 (2004/06/07) ヘッ??の日付け表示に、Locale を加味できるように変更
365 * @og.rev 3.6.1.0 (2005/01/05) startDay,endDay,useSeqDay 属?追?
366 */
367 private void paramInit() {
368
369 String strGroupCols = getParam( ViewGanttTableParam.GROUP_COLUMNS_KEY ,ViewGanttTableParam.GROUP_COLUMNS_VALUE );
370 String strColDuration = getParam( ViewGanttTableParam.DURATION_COLUMN_KEY ,null );
371 String strColDystart = getParam( ViewGanttTableParam.DYSTART_COLUMN_KEY ,ViewGanttTableParam.DYSTART_COLUMN_VALUE );
372 formatDystart = getParam( ViewGanttTableParam.DYSTART_FORMAT_KEY ,ViewGanttTableParam.DYSTART_FORMAT_VALUE );
373 String strMinDuration = getParam( ViewGanttTableParam.MIN_DURATION_KEY ,ViewGanttTableParam.MIN_DURATION_VALUE );
374 String strHeadDuration = getParam( ViewGanttTableParam.HEADER_DURATION_KEY ,strMinDuration );
375 headerLocale = getParam( ViewGanttTableParam.HEADER_LOCALE_KEY ,ViewGanttTableParam.HEADER_LOCALE_VALUE );
376 startDay = getParam( ViewGanttTableParam.START_DAY_KEY ,null ); // 3.6.1.0 (2005/01/05)
377 endDay = getParam( ViewGanttTableParam.END_DAY_KEY ,null ); // 3.6.1.0 (2005/01/05)
378
379 String seqDay = getParam( ViewGanttTableParam.USE_SEQ_DAY_KEY ,ViewGanttTableParam.USE_SEQ_DAY_VALUE ); // 3.6.1.0 (2005/01/05)
380 useSeqDay = Boolean.valueOf( seqDay ).booleanValue() ;
381
382 DBTableModel table = getDBTableModel();
383
384 // 3.5.5.9 (2004/06/07) durationColumn を指定しな??合?処?追?
385 if( strColDuration != null ) {
386 posDuration = table.getColumnNo( strColDuration );
387 }
388
389 posDystart = table.getColumnNo( strColDystart );
390
391 String[] groupKeys = StringUtil.csv2Array(strGroupCols);
392 groupCols = new int[groupKeys.length];
393 for( int nIndex = 0; nIndex < groupCols.length ; nIndex++) {
394 groupCols[nIndex] = table.getColumnNo( groupKeys[nIndex] );
395 }
396
397 minDuration = StringUtil.parseDouble( strMinDuration );
398 if( minDuration <= 0.0d ) {
399 String errMsg = "?期間単?minDuration)が???かそれ以下です?";
400 throw new HybsSystemException( errMsg );
401 }
402
403 headerDuration = StringUtil.parseDouble( strHeadDuration );
404 if( headerDuration <= 0.0d ) {
405 String errMsg = "ヘッ??の表示期間(headerDuration)が???かそれ以下です?";
406 throw new HybsSystemException( errMsg );
407 }
408
409 // 3.5.5.9 (2004/06/07) エラーチェ?の強?
410 // 4.0.0 (2005/01/31) Equality checks with floating point numbers can lead to unexpected behavior.
411 if( posDuration < 0 && (
412 Double.compare( minDuration,1.0d ) != 0 ||
413 Double.compare( headerDuration,1.0d ) != 0 ) ) {
414
415 String errMsg = "期間カラ?durationColumn)を指定しな??合??
416 + "?期間単?minDuration)および?
417 + "ヘッ??の表示期間(headerDuration)?'1' 以外に設定できません?;
418 throw new HybsSystemException( errMsg );
419 }
420 }
421
422 /**
423 * 上下行???タが同じグルプかど?をチェ?する?
424 *
425 * @param nRowIndex ??ブルモ?の行番号
426 * @param astrOldValues 古?ルプデータ
427 *
428 * @return 使用可能(true)/ 使用不可能 (false)
429 */
430 private boolean isSameGroup(final int nRowIndex, final String[] astrOldValues) {
431 boolean bRet = (groupCols.length > 0);
432 if( bRet ) {
433 for( int nIndex = 0; bRet && ( nIndex < groupCols.length ); nIndex++) {
434 bRet = ( astrOldValues[nIndex].equals(getValue(nRowIndex, groupCols[nIndex])));
435 }
436
437 // 不??時に astrOldValues に 新しい値を設定しておきます?
438 if(!bRet) {
439 for( int nIndex = 0; nIndex < groupCols.length; nIndex++) {
440 astrOldValues[nIndex] = getValue(nRowIndex, groupCols[nIndex]);
441 }
442 }
443 }
444
445 return bRet;
446 }
447
448 /**
449 * DBTableModel から ??ブルのタグ??を作?して返します?
450 *
451 * @og.rev 3.5.0.0 (2003/09/17) <tr>属?は、?のフォーマット?まま使用します?
452 * @og.rev 3.5.1.0 (2003/10/03) Noカラ?、numberType 属?を追?
453 * @og.rev 3.5.2.0 (2003/10/20) ヘッ??繰り返し部をgetHeadLine()へ移?
454 * @og.rev 3.5.3.1 (2003/10/31) VERCHAR2 ?VARCHAR2 に修正?
455 * @og.rev 3.5.4.0 (2003/11/25) TableFormatter クラスを使用するように変更?
456 * @og.rev 3.5.6.5 (2004/08/09) thead に、id="header" を追?
457 * @og.rev 4.0.0.0 (2005/01/31) DBColumn の 属?(CLS_NM)から、DBTYPEに変更
458 *
459 * @return ??ブルのタグ??
460 */
461 @Override
462 protected String getTableHead() {
463 headerFormat.makeFormat( getDBTableModel() );
464
465 StringBuilder buf = new StringBuilder( HybsSystem.BUFFER_MIDDLE );
466 // 3.5.5.0 (2004/03/12) No ?のも?の作?判断追?
467 if( isNumberDisplay() ) {
468 buf.append("<colgroup class=\"X\" />"); // 4.0.0 (2005/01/31)
469 buf.append("<colgroup class=\"BIT\" />");
470 buf.append("<colgroup class=\"S9\" />"); // 4.0.0 (2005/01/31)
471 buf.append(HybsSystem.CR);
472 }
473
474 // 3.5.2.0 (2003/10/20) ヘッ??繰り返し部をgetHeadLine()へ移?
475 buf.append("<thead id=\"header\">").append( HybsSystem.CR ); // 3.5.6.5 (2004/08/09)
476 buf.append( getHeadLine() );
477 buf.append("</thead>").append( HybsSystem.CR );
478
479 return buf.toString();
480 }
481
482 /**
483 * ヘッ??繰り返し部を?getTableHead()メソ?から??
484 *
485 * @og.rev 3.5.2.0 (2003/10/20) 新規作?
486 * @og.rev 3.5.4.0 (2003/11/25) TableFormatter クラスを使用するように変更?
487 * @og.rev 3.5.4.3 (2004/01/05) useCheckControl 属?の機?を追?
488 * @og.rev 3.5.4.6 (2004/01/30) numberType="none" 時?処?追?Noラベルを?さな?
489 * @og.rev 3.5.4.7 (2004/02/06) ヘッ??にソート機?用のリンクを追?ます?
490 * @og.rev 3.5.5.0 (2004/03/12) systemFormat(例:[KEY.カラ?]形式?の対?
491 * @og.rev 3.7.0.1 (2005/01/31) 全件チェ?コントロール処?更
492 * @og.rev 5.0.0.3 (2009/09/22) itdの有無を取得します?
493 *
494 * @return ??ブルのタグ??
495 */
496 @Override
497 protected String getHeadLine() {
498 if( headerLine != null ) { return headerLine; } // キャ?ュを返す?
499
500 StringBuilder buf = new StringBuilder( HybsSystem.BUFFER_MIDDLE );
501
502 buf.append( headerFormat.getTrTag() ).append( HybsSystem.CR );
503
504 // 3.5.5.0 (2004/03/12) No ?のも?の作?判断追?
505 if( isNumberDisplay() ) {
506 // 3.5.4.3 (2004/01/05) 追??
507 if( isUseCheckControl() && "checkbox".equals( getSelectedType() ) ) {
508 buf.append(" <th" ).append( headerFormat.getRowspan() ).append("></th>");
509 buf.append(" <th" ).append( headerFormat.getRowspan() );
510 buf.append(">").append( getAllCheckControl() ).append( "</th>");
511 buf.append(" <th" ).append( headerFormat.getRowspan() );
512 buf.append(">").append( getNumberHeader() ).append("</th>"); // 3.5.4.6 (2004/01/30)
513 }
514 else {
515 buf.append(" <th colspan=\"3\"");
516 buf.append( headerFormat.getRowspan() );
517 buf.append(">").append( getNumberHeader() ).append("</th>"); // 3.5.4.6 (2004/01/30)
518 }
519 }
520
521 int cl = 0;
522 for( ; cl < headerFormat.getLocationSize(); cl++ ) {
523 buf.append( headerFormat.getFormat(cl) );
524 int loc = headerFormat.getLocation(cl);
525 if( loc >= 0 ) { buf.append( getSortedColumnLabel(loc) ); }
526 }
527 buf.append( headerFormat.getFormat(cl) ).append( HybsSystem.CR );
528
529 // 5.0.0.3 (2009/09/22) ITD_MARKERの条件判断追?
530 if( buf.indexOf( TableFormatter.HYBS_ITD_MARKER ) >= 0 ){
531 useItd = true;
532 }
533 headerLine = StringUtil.replace(buf.toString(), TableFormatter.HYBS_ITD_MARKER, ganttHeadLine);
534
535 return headerLine;
536 }
537
538 /**
539 * ガントチャート??ー繰り返し部を?getTableHead()メソ?から??
540 * こ?メソ?は、durationColumn を利用して??続日付け??タを作?します?
541 * ??タは?始日と期間??タを持ち、??ーは連続日付けになります?
542 * ヘッ??の期間(headerDuration)と??タの?期?minDuration)が異なる為?
543 * ??の行データより、最終日を求め、headerDuration で割り算した?数の連続日数?
544 * 表示させて?す?
545 *
546 * @og.rev 3.5.5.9 (2004/06/07) ヘッ??の日付け表示に、Locale を加味できるように変更
547 * @og.rev 3.5.6.0 (2004/06/18) ithFormat 変数削除
548 *
549 * @param startNo 開始行番号
550 * @param lastNo ?行番号
551 *
552 * @return ??ブルのタグ??
553 */
554 private String getGanttHead(final int startNo, final int lastNo) {
555 String[] astrOldGroupKeys = new String[groupCols.length];
556 for( int nIndex =0; nIndex < astrOldGroupKeys.length; nIndex++) {
557 astrOldGroupKeys[nIndex] = "";
558 }
559
560 // 3.5.5.9 (2004/06/07) ヘッ??の日付け表示に、Locale を加味できるように変更
561 Locale local = new Locale( headerLocale );
562 SimpleDateFormat fmtDate = new SimpleDateFormat( formatDystart,local );
563
564 double nSumDuration = 0.0d ;
565 Date dFirst = null ;
566
567 for( int nRowUp = startNo; nRowUp < lastNo; nRowUp++ ) {
568 // ガントでは、データのスキ??は行いません?
569
570 // ??の?また?、ブレイクするまで
571 if( isSameGroup(nRowUp, astrOldGroupKeys) || (nRowUp == startNo) ) {
572 nSumDuration += StringUtil.parseDouble( getValue(nRowUp, posDuration) );
573 try {
574 if( dFirst == null ) {
575 dFirst = fmtDate.parse(getValue(nRowUp, posDystart));
576 }
577 }
578 catch ( ParseException ex) {
579 String errMsg = "DYSTARTに?した日付形式と異なるデータが存在して?す?"
580 + "[" + getValue(nRowUp , posDystart) + "] => ["
581 + fmtDate.toPattern() + "]" ;
582 throw new HybsSystemException( errMsg,ex );
583 }
584 }
585 else { break; }
586 }
587
588 String thVal = "" ; // <td ???> の <td 以下? ???部??属????
589 String ymdForm = "MM/dd" ; // td タグの BODY 部 の 日付けフォーマッ?
590
591 if( headerFormat != null ) {
592 String format = headerFormat.getItdBody().trim() ;
593 Matcher matcher = cpTdTh.matcher(format);
594 if( matcher.find() ) {
595 thVal = matcher.group(2);
596 ymdForm = matcher.group(3);
597 }
598 }
599
600 try {
601 fmtDate.applyPattern(ymdForm);
602 }
603 catch(IllegalArgumentException eArg) {
604 String errMsg = "theadの??itdの??に?された日付?形式が不正です?(" + ymdForm + ")";
605 throw new HybsSystemException( errMsg,eArg );
606 }
607
608 int colspan = (int)Math.round( headerDuration / minDuration );
609 final String th ;
610 if( colspan == 1 ) { th = "<th " + thVal + ">"; }
611 else { th = "<th colspan=\"" + colspan + "\" " + thVal + ">" ; }
612
613 Calendar cal = Calendar.getInstance() ;
614 cal.setTime( dFirst );
615
616 maxDayCnt = (int)Math.round(nSumDuration / headerDuration) ; // 3.5.5.9 (2004/06/07)
617 int addDate ;
618 int field ;
619 if( headerDuration >= 1.0d ) {
620 addDate = (int)Math.round( headerDuration );
621 field = Calendar.DATE ;
622 }
623 else {
624 addDate = (int)Math.round( 24.0d * headerDuration );
625 field = Calendar.HOUR_OF_DAY ;
626 }
627
628 // 端数を指定すると、積算誤差がでます?
629 StringBuilder buf = new StringBuilder( HybsSystem.BUFFER_MIDDLE );
630
631 for( int nIndex = 0; nIndex < maxDayCnt; nIndex++ ) {
632 buf.append( th );
633 buf.append( fmtDate.format( cal.getTime() ) );
634 buf.append( "</th>" );
635 cal.add( field ,addDate );
636 }
637
638 return buf.toString();
639 }
640
641 /**
642 * ガントチャート??ー繰り返し部を?getTableHead()メソ?から??
643 * こ?メソ?は、durationColumn が指定されて???合?処?行います?
644 * ??タは、すべての行に関して、同じ日付けの??タとして扱われます?
645 * よって、行間で、日付け違いの並び?なって?とずれることがあります?
646 * ヘッ??は、最初?行?日付けをそのまま表示させます?よって、データと
647 * 日付けが同期されて?ば、不?続な日付けのヘッ??を表示させることも可能です?
648 * ヘッ??の期間(headerDuration)と??タの?期?minDuration)は?
649 * ともに?1' であることが前提です?
650 * useSeqDay 属?に?true" を設定すると?始日(startDay)と終?(endDay)
651 * の日付けを?続した日付けとします?開始日(startDay)??(endDay)が指?
652 * されて???合?、dystartColumn 属?で?されたカラ??値の?値、最小??
653 * 自動セ?します?
654 *
655 * @og.rev 3.5.5.9 (2004/06/07) 新規作?
656 * @og.rev 3.5.6.0 (2004/06/18) ithFormat 変数削除
657 * @og.rev 3.6.1.0 (2005/01/05) startDay,endDay,useSeqDay 属?追?
658 *
659 * @param startNo 開始行番号
660 * @param lastNo ?行番号
661 *
662 * @return ??ブルのタグ??
663 */
664 private String getGanttHeadNoDuration(final int startNo, final int lastNo) {
665 String[] astrOldGroupKeys = new String[groupCols.length];
666 for( int nIndex =0; nIndex < astrOldGroupKeys.length; nIndex++) {
667 astrOldGroupKeys[nIndex] = "";
668 }
669
670 String thVal = "" ; // <td ???> の <td 以下? ???部??属????
671 String ymdForm = "MM/dd" ; // td タグの BODY 部 の 日付けフォーマッ?
672
673 if( headerFormat != null ) {
674 String format = headerFormat.getItdBody().trim() ;
675 Matcher matcher = cpTdTh.matcher(format);
676 if( matcher.find() ) {
677 thVal = matcher.group(2);
678 ymdForm = matcher.group(3);
679 }
680 }
681 String th = "<th " + thVal + ">";
682
683 // 3.5.5.9 (2004/06/07) ヘッ??の日付け表示に、Locale を加味できるように変更
684 Locale local = new Locale( headerLocale );
685 SimpleDateFormat dataFmt = new SimpleDateFormat( formatDystart,local );
686 SimpleDateFormat headFmt = new SimpleDateFormat( ymdForm,Locale.JAPAN );
687 Calendar cal = Calendar.getInstance() ;
688
689 TreeSet<String> daySet = new TreeSet<String>();
690 for( int nRowUp = startNo; nRowUp < lastNo; nRowUp++ ) {
691 // ガントでは、データのスキ??は行いません?
692
693 String day = getValue(nRowUp, posDystart);
694 daySet.add( day );
695 }
696 // 3.6.1.0 (2005/01/05)
697 if( useSeqDay ) {
698 if( startDay == null ) { startDay = daySet.first() ; }
699 if( endDay == null ) { endDay = daySet.last() ; }
700
701 try {
702 Calendar startCal = Calendar.getInstance() ;
703 Date dStart = dataFmt.parse( startDay );
704 startCal.setTime( dStart );
705
706 Calendar endCal = Calendar.getInstance() ;
707 Date dEnd = dataFmt.parse( endDay );
708 endCal.setTime( dEnd );
709 endCal.set( Calendar.HOUR_OF_DAY,12 ); // 日付け比?る為?2時間?めておく?
710
711 while( startCal.before( endCal ) ) {
712 daySet.add( dataFmt.format( startCal.getTime() ) );
713 startCal.add( Calendar.DATE ,1 );
714 }
715 }
716 catch ( ParseException ex) {
717 String errMsg = "startDay,endDayに?した日付形式と異なるデータが存在して?す?"
718 + "[" + startDay + "],["
719 + "[" + endDay + "] => ["
720 + dataFmt.toPattern() + "]" ;
721 throw new HybsSystemException( errMsg,ex );
722 }
723 }
724
725 headDays = daySet.toArray( new String[daySet.size()] ); // 4.0.0 (2005/01/31)
726
727 StringBuilder buf = new StringBuilder( HybsSystem.BUFFER_MIDDLE );
728 for( int i=0; i<headDays.length; i++ ) {
729
730 try {
731 cal.setTime( dataFmt.parse(headDays[i]) );
732 buf.append( th );
733 buf.append( headFmt.format( cal.getTime() ) );
734 buf.append( "</th>" );
735 }
736 catch ( ParseException ex) {
737 String errMsg = "DYSTARTに?した日付形式と異なるデータが存在して?す?"
738 + "[" + headDays[i] + "] => ["
739 + dataFmt.toPattern() + "]" ;
740 throw new HybsSystemException( errMsg,ex );
741 }
742 }
743
744 return buf.toString();
745 }
746
747 /**
748 * DBTableModel から ??ブルのタグ??を作?して返します?
749 *
750 * @og.rev 3.5.0.0 (2003/09/17) <tr>属?は、?のフォーマット?まま使用します?
751 * @og.rev 3.5.1.0 (2003/10/03) Noカラ?、numberType 属?を追?
752 * @og.rev 3.5.4.0 (2003/11/25) TableFormatter クラスを使用するように変更?
753 * @og.rev 3.5.4.7 (2004/02/06) ヘッ??にソート機?用のリンクを追?ます?
754 * @og.rev 3.5.5.0 (2004/03/12) systemFormat(例:[KEY.カラ?]形式?の対?
755 *
756 * @return ??ブルのタグ??
757 */
758 protected String getTableFoot() {
759 footerFormat.makeFormat( getDBTableModel() );
760
761 StringBuilder buf = new StringBuilder( HybsSystem.BUFFER_MIDDLE );
762
763 buf.append("<tfoot>").append( HybsSystem.CR );
764 buf.append( footerFormat.getTrTag() ).append( HybsSystem.CR );
765
766 // 3.5.5.0 (2004/03/12) No ?のも?の作?判断追?
767 if( isNumberDisplay() ) {
768 buf.append(" <th");
769 buf.append(" colspan=\"3\"");
770 buf.append( footerFormat.getRowspan() );
771 buf.append("></th>");
772 }
773
774 int cl = 0;
775 for( ; cl < footerFormat.getLocationSize(); cl++ ) {
776 int loc = footerFormat.getLocation(cl);
777 if( loc >= 0 ) { buf.append( getSortedColumnLabel(loc) ); }
778 }
779 buf.append( footerFormat.getFormat(cl) ).append( HybsSystem.CR );
780 buf.append("</tfoot>").append( HybsSystem.CR );
781
782 return buf.toString();
783 }
784
785 /**
786 * itaタグの中身を形式化する?
787 *
788 * @og.rev 3.5.5.0 (2004/03/12) systemFormat(例:[KEY.カラ?]形式?の対?
789 * @og.rev 3.5.5.9 (2004/06/07) durationColumn を指定しな??合?処?追?
790 * @og.rev 3.5.6.0 (2004/06/18) itdタグの[$xx] , [#xx]対?
791 * @og.rev 3.5.6.0 (2004/06/18) '!' 値のみ 追?既存? '$' は、レン?ー
792 *
793 * @param nTblRow ??ブルモ?の行番号
794 * @param myIteFormat TableFormatteオブジェク?
795 * @param inputBuf 出力データバ?ファ
796 *
797 * @return StringBuilder戻り?
798 */
799 StringBuilder formatItd(final int nTblRow, final TableFormatter myIteFormat, final StringBuilder inputBuf ) {
800 if( myIteFormat == null ) { return new StringBuilder( "" ); }
801
802 final StringBuilder strBuf ;
803 if( inputBuf != null ) { strBuf = inputBuf; }
804 else { strBuf = new StringBuilder( HybsSystem.BUFFER_LARGE ); }
805
806 int colspan = 1;
807 if( posDuration >= 0 ) {
808 // 3.7.0.0 (2005/01/18) 小数点の桁落ち対?
809 colspan = (int)Math.round( StringUtil.parseDouble( getValue(nTblRow, posDuration) ) / minDuration );
810 }
811 else { // 日付けヘッ??未??、空タグを?力しておく
812 String today = getValue(nTblRow, posDystart);
813 int comp = headDays[headDaysCnt].compareTo( today );
814 headDaysCnt++ ;
815 while( comp < 0 && headDaysCnt < headDays.length ) {
816 strBuf.append( "<td></td>" );
817 comp = headDays[headDaysCnt].compareTo( today );
818 headDaysCnt++ ;
819 }
820 if( comp != 0 ) { // 見つからなかっ?先に日付けが無くなっ?
821 String errMsg = "日付けヘッ??と日付け??タに矛盾が発生して?す?"
822 + HybsSystem.CR
823 + "groupColumns で日付けがユニ?クになって??能性があります?"
824 + "row=[" + (nTblRow +1) + "] , today=[" + today + "]" ;
825 throw new HybsSystemException( errMsg );
826 }
827 }
828
829 int cl = 0;
830 for( ; cl < myIteFormat.getLocationSize(); cl++ ) {
831 String fmt = myIteFormat.getFormat(cl) ;
832 int loc = myIteFormat.getLocation(cl); // 3.5.6.0
833 if( cl == 0 && colspan != 1 ) {
834 fmt = StringUtil.replace(fmt , "<td", "<td colspan=\"" + colspan + "\"");
835 }
836 strBuf.append( fmt ); // 3.5.6.0
837 if( loc >= 0 ) {
838 switch( myIteFormat.getType(cl) ) {
839 case '#' : strBuf.append( getColumnLabel(loc) ); break;
840 case '$' : strBuf.append( getRendererValue(nTblRow,loc) ); break;
841 case '!' : strBuf.append( getValue(nTblRow,loc) ); break;
842 default : strBuf.append( getValueLabel(nTblRow,loc) ); break;
843 }
844 }
845 else {
846 strBuf.append( myIteFormat.getSystemFormat(nTblRow,loc) );
847 }
848 }
849 strBuf.append(myIteFormat.getFormat(cl));
850
851 return strBuf;
852 }
853
854 /**
855 * フォーマットを設定します?
856 *
857 * @og.rev 3.5.4.0 (2003/11/25) 新規作?
858 * @og.rev 3.5.4.4 (2004/01/16) 配?の?数を変更
859 * @og.rev 3.5.6.0 (2004/06/18) ithFormat , itdFormat 変数削除
860 *
861 * @param list TableFormatterのリス?
862 */
863 @Override
864 public void setFormatterList( final List<TableFormatter> list ) { // 4.3.3.6 (2008/11/15) Generics警告対?
865 bodyFormats = new TableFormatter[BODYFORMAT_MAX_COUNT];
866
867 bodyFormatsCount = 0;
868 for( int i=0; i<list.size(); i++ ) {
869 TableFormatter format = list.get( i ); // 4.3.3.6 (2008/11/15) Generics警告対?
870
871 switch( format.getFormatType() ) {
872 case TYPE_HEAD : headerFormat = format; break;
873 case TYPE_BODY : bodyFormats[bodyFormatsCount++] = format; break;
874 case TYPE_FOOT : footerFormat = format; break;
875 default : String errMsg = "FormatterType の定義外?値が指定されました?;
876 // 4.3.4.4 (2009/01/01)
877 throw new HybsSystemException( errMsg );
878 }
879 // 3.5.6.0 (2004/06/18) ?
880 }
881
882 // 3.5.6.0 (2004/06/18) itdFormats 処??
883 // tbody 配??け設定しておきます?
884 itdFormats = new TableFormatter[bodyFormatsCount];
885 for( int i=0; i<bodyFormatsCount; i++ ) {
886 String format = bodyFormats[i].getItdBody().trim();
887 itdFormats[i] = new TableFormatter();
888 itdFormats[i].setFormat( format );
889 }
890 }
891
892 /**
893 * フォーマットメソ?を使用できるかど?を問?わせます?
894 *
895 * @return 使用可能(true)/ 使用不可能 (false)
896 */
897 @Override
898 public boolean canUseFormat() {
899 return true;
900 }
901
902 /**
903 * 表示?の編?並び替?が可能かど?を返しま?
904 *
905 * @og.rev 5.1.6.0 (2010/05/01) 新規追?
906 *
907 * @return 表示?の編?並び替?が可能かど?(false:不可能)
908 */
909 @Override
910 public boolean isEditable() {
911 return false;
912 }
913 }