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.hayabusa.taglib; 017 018import org.opengion.hayabusa.common.HybsSystem; 019import org.opengion.hayabusa.html.ViewCrossTableParam; 020 021import static org.opengion.fukurou.util.StringUtil.nval ; 022 023import java.io.ObjectOutputStream; 024import java.io.ObjectInputStream; 025import java.io.IOException; 026 027/** 028 * viewタグの viewFormType が HTMLCrossTable の場合にパラメータを設定します。 029 * 030 * クロス集計を行う、ViewForm_HTMLCrossTable クラスに対して、各種パラメータを 031 * 設定します。 032 * パラメータが設定されていない場合は、ViewCrossTableParam の初期値が使用されます。 033 * (パラメータを使用するには、viewタグのuseParam 属性をtrueに設定する必要があります。) 034 * 035 * SELECT文は、CROSS集計機能を利用して求めます。そのときのフォーマットは、 036 * ヘッダー1..N,縦,横,計1..N になります。 037 * ヘッダー部は、複数指定できますが、デフォルトではヘッダーNがキーブレイクすると 038 * 合計用のヘッダーが挿入されます。また、ヘッダーは、前段と同じ値の場合は、表示しません。 039 * 合計は、複数並べることができますが、sumNumber で指定しておく必要があります。 040 * 041 * 各属性は、{@XXXX} 変数が使用できます。 042 * これは、ServletRequest から、XXXX をキーに値を取り出し,この変数に割り当てます。 043 * つまり、このXXXXをキーにリクエストすれば、この変数に値をセットすることができます。 044 * 045 * http://localhost/query.jsp?KEY1=VLA1&KEY2=VAL2 046 * 047 * のようなリクエストで、{@KEY1} とすれば、 VAL1 がセットされます。 048 * 049 * @og.formSample 050 * ●形式:<og:crossParam breakColumn="ZZZ" noGroupColumns="AAA,BBB" sumNumber="2" /> 051 * ●body:なし 052 * 053 * ●Tag定義: 054 * <og:crossParam 055 * cubeXColumn 【TAG】CUBE計算の1つ目(X)カラムを指定します 056 * cubeYColumn 【TAG】CUBE計算の2つ目(Y)カラムを指定します 057 * sumNumber 【TAG】合計値のカラム数を設定します 058 * breakColumn 【TAG】ブレークによりヘッダー部を出力させるカラム名をセットします(初期値:ヘッダーN) 059 * noGroupColumns 【TAG】カラム値を前段と比較して同じ場合でも表示させるカラム名をセットします 060 * shokeiLabel 【TAG】列小計のカラムに表示するラベルIDを指定します(初期値:空文字列) 061 * gokeiLabel 【TAG】列合計のカラムに表示するラベルIDを指定します(初期値:空文字列) 062 * cubeSortType 【TAG】CUBE Y の列ヘッダーのソート方式を指定します(初期値:LOAD) 063 * gokeiSortDir 【TAG】合計行のソート有無とその方向[true:正方向/false:逆方向/null:ソートしない]を指定します(初期値:null) 064 * useHeaderColumn 【TAG】ヘッダーカラムにレンデラー、エディターを適用するかを指定します(初期値:false) 065 * useClassAdd 【TAG】各列情報のclass属性に、カラム名などを付与するかどうかを指定します(初期値:false) 066 * firstClmGokei 【TAG】合計列をCUBEの先頭部分に出すかどうか[true/false]を指定します(初期値:false) 067 * saveTableId 【TAG】クロス集計結果の DBTableModel をセーブするセッションキーワードを指定します 068 * saveScope 【TAG】クロス集計結果の DBTableModel をセーブする scope を指定します 069 * useHeaderResource 【TAG】ヘッダー表示にラベルリソースを適用するかどうかを指定します(初期値:false) 070 * headerCodeColumn 【TAG】ヘッダー表示に利用するコードを持つカラムを指定します(初期値:空文字列) 071 * debug 【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false) 072 * /> 073 * 074 * ●使用例 075 * ViewFormTag の viewFormType が、HTMLCrossTable の場合に使用します。 076 * useParam 属性を設定しておかないと、使用されません。 077 * <og:view 078 * viewFormType = "HTMLCrossTable" 079 * command = "{@command}" 080 * startNo = "0" 081 * pageSize = "20" 082 * <b>useParam = "true"</b> 083 * > 084 * <og:crossParam 085 * breakColumn = "ZZZ" : ブレークによりヘッダー部を出力させるカラム名 086 * noGroupColumns = "AAA,BBB" : カラム値を前段と比較して同じ場合でも表示させるカラム名 087 * cubeXColumn = "CUBE_X" : CUBE計算の1つ目(X)カラムを指定 088 * cubeYColumn = "CUBE_Y" : CUBE計算の2つ目(Y)カラムを指定 089 * shokeiLabel = "SHOKEI" : 列小計のカラムに表示するラベルID(初期値:SHOKEI) 090 * gokeiLabel = "GOKEI" : 列合計のカラムに表示するラベルID(初期値:GOKEI) 091 * sumNumber = "2" : 合計値のカラム数(初期値1) 092 * cubeSortType = "NUMBER" : CUBE Y の列ヘッダーのソート方式を指定[STRING/NUMBER/LOAD] 093 * gokeiSortDir = "false" : 合計行のソート有無とその方向(正方向/逆方向)を指定[true/false/null] 094 * firstClmGokei = "true" : 合計列をCUBEの先頭部分に出すかどうかを指定[false/true/null] 095 * useHeaderColumn= "true" : ヘッダーカラムにレンデラー、エディターを適用するかどうかを指定[false/true/null] 096 * saveTableId = "DEFAULT" : クロス集計結果の DBTableModel をセーブするセッションキーワードを指定 097 * useClassAdd = "true" : String 各列情報のclass属性に、カラム名などを付与するかどうかを指定[false/true/null] 098 * /> 099 * </og:view > 100 * 101 * @og.group 画面表示 102 * 103 * @version 4.0 104 * @author Kazuhiko Hasegawa 105 * @since JDK5.0, 106 */ 107public class ViewCrossParamTag extends ViewParamTag { 108 //* このプログラムのVERSION文字列を設定します。 {@value} */ 109 private static final String VERSION = "5.5.5.0 (2012/07/28)" ; 110 111 private static final long serialVersionUID = 555020120728L ; 112 113 /** 114 * 【TAG】ブレークによりヘッダー部を出力させるカラム名をセットします(初期値:ヘッダーN)。 115 * 116 * @og.tag 117 * CROSS集計で求めたフォーマットは、『ヘッダー1..N,縦,横,計1..N 』です。 118 * ヘッダー部は、複数指定できますが、デフォルトではヘッダーNがキーブレイクすると 119 * 合計用のヘッダーが挿入されます。 120 * このヘッダーNそのものが、集計フィールドでなく、単なる属性の場合は、 121 * キーブレイクして欲しくない為、breakColumn="ヘッダーN-1" を指定します。 122 * 初期値は、"ヘッダーN" です。 123 * 124 * @param clm ブレークさせるカラム名 125 */ 126 public void setBreakColumn( final String clm ) { 127 putParam( ViewCrossTableParam.BREAK_COLUMN_KEY, 128 nval( getRequestParameter( clm ),null ) ); 129 } 130 131 /** 132 * 【TAG】カラム値を前段と比較して同じ場合でも表示させるカラム名をセットします。 133 * 134 * @og.tag 135 * CROSS集計で求めたフォーマットは、『ヘッダー1..N,縦,横,計1..N 』です。 136 * ヘッダー部は、キーブレイクする都度、ヘッダーを出力します。それまでは、 137 * 各ヘッダーの値が、前段(同一カラムの先の値)と同じ場合は、空白にします。 138 * こうする事で、値のグループ化が一目で判ります。(初期設定) 139 * このヘッダーが、集計フィールドでなく、単なる属性の場合は、 140 * 空白ではなく、値として表示したい為、グループ化しない事を指定します。 141 * 142 * @param clms グループ化(空白化)したくないカラム(カンマ区切り) 143 */ 144 public void setNoGroupColumns( final String clms ) { 145 putParam( ViewCrossTableParam.NO_GROUP_COLUMNS_KEY, 146 nval( getRequestParameter( clms ),null ) ); 147 } 148 149 /** 150 * 【TAG】合計値のカラム数を設定します(初期値:1)。 151 * 152 * @og.tag 153 * CROSS集計で求めたフォーマットは、『ヘッダー1..N,縦,横,計1..N 』です。 154 * 合計は、複数並べることができますが、sumNumber で指定しておく必要があります。 155 * 初期値は、1 です。 156 * 157 * @param no 合計値のカラム数(初期値1) 158 */ 159 public void setSumNumber( final String no ) { 160 putParam( ViewCrossTableParam.SUM_NUMBER_KEY, 161 nval( getRequestParameter( no ),"1" ) ); 162 } 163 164 /** 165 * 【TAG】列小計のカラムに表示するラベルIDを指定します(初期値:空文字列)。 166 * 167 * @og.tag 168 * 各列の小計のラベルIDを登録します。登録する文字列は、ラベルリソースに 169 * 定義しておいて下さい。 170 * 初期値は、空文字列("")です。 171 * 172 * @og.rev 3.7.1.1 (2005/05/31) 初期値を "SHOKEI" に設定します。 173 * 174 * @param id 列小計のカラムに表示するラベルID 175 */ 176 public void setShokeiLabel( final String id ) { 177 String label = nval( getRequestParameter( id ),"SHOKEI" ); 178 putParam( ViewCrossTableParam.SHOKEI_LABEL_KEY, getLabel( label ) ); 179 } 180 181 /** 182 * 【TAG】列合計のカラムに表示するラベルIDを指定します(初期値:空文字列)。 183 * 184 * @og.tag 185 * 各列の合計のラベルIDを登録します。登録する文字列は、ラベルリソースに 186 * 定義しておいて下さい。 187 * 初期値は、空文字列("")です。 188 * 189 * @og.rev 3.7.1.1 (2005/05/31) 初期値を "GOKEI" に設定します。 190 * 191 * @param id 列合計のカラムに表示するラベルID 192 */ 193 public void setGokeiLabel( final String id ) { 194 String label = nval( getRequestParameter( id ),"GOKEI" ); 195 putParam( ViewCrossTableParam.GOKEI_LABEL_KEY, getLabel( label ) ); 196 } 197 198 /** 199 * 【TAG】CUBE計算の1つ目(X)カラムを指定します。 200 * 201 * @og.tag 202 * 列方向のキーとなるカラム名を指定します。 203 * 初期値は、互換性の関係より、sumNumber より逆計算します。 204 * 205 * @og.rev 3.5.5.9 (2004/06/07) 新規追加 206 * 207 * @param cubeX 列合計のカラムに表示するラベルID 208 */ 209 public void setCubeXColumn( final String cubeX ) { 210 putParam( ViewCrossTableParam.CUBE_X_COLUMN_KEY, 211 nval( getRequestParameter( cubeX ),null ) ); 212 } 213 214 /** 215 * 【TAG】CUBE計算の2つ目(Y)カラムを指定します。 216 * 217 * @og.tag 218 * 行方向のキーとなるカラム名を指定します。 219 * 初期値は、互換性の関係より、sumNumber より逆計算します。 220 * 221 * @og.rev 3.5.5.9 (2004/06/07) 新規追加 222 * 223 * @param cubeY 列合計のカラムに表示するラベルID 224 */ 225 public void setCubeYColumn( final String cubeY ) { 226 putParam( ViewCrossTableParam.CUBE_Y_COLUMN_KEY, 227 nval( getRequestParameter( cubeY ),null ) ); 228 } 229 230 /** 231 * 【TAG】CUBE Y の列ヘッダーのソート方式を指定します(初期値:LOAD)。 232 * 233 * @og.tag 234 * CUBEのヘッダーに対応するカラム列をソート表示する場合の方式を指定します。 235 * 種類として、STRING,NUMBER,LOAD,があります。 236 * 初期値(指定無し)は、LOAD(取り込み順にセット)です。 237 * 238 * @og.rev 3.5.6.3 (2004/07/12) 新規追加 239 * 240 * @param cubeSortType CUBE Y の列ヘッダーのソート方式[STRING,NUMBER,LOAD] 241 */ 242 public void setCubeSortType( final String cubeSortType ) { 243 putParam( ViewCrossTableParam.CUBE_SORT_TYPE_KEY, 244 nval( getRequestParameter( cubeSortType ),null ) ); 245 } 246 247 /** 248 * 【TAG】合計行のソート有無とその方向[true:正方向/false:逆方向/null:ソートしない]を指定します(初期値:null)。 249 * 250 * @og.tag 251 * 最も最後の合計カラムにソートを行うかどうか、その時の方向を指定します。 252 * true/false 以外の文字列では、ソートを行いません。trueは、正方向(昇順)で、 253 * falseが逆方向(降順)になります。 254 * 初期値(指定無し)は、ソートしない(null)です。 255 * 256 * @og.rev 3.5.6.3 (2004/07/12) 新規追加 257 * 258 * @param gokeiSortDir 合計行のソート有無とその方向[true:正方向/false:逆方向/null:ソートしない] 259 */ 260 public void setGokeiSortDir( final String gokeiSortDir ) { 261 putParam( ViewCrossTableParam.GOKEI_SORT_DIR_KEY, 262 nval( getRequestParameter( gokeiSortDir ),null ) ); 263 } 264 265 /** 266 * 【TAG】合計列をCUBEの先頭部分に出すかどうか[true/false]を指定します(初期値:false)。 267 * 268 * @og.tag 269 * 合計列を最終列に出力するか、CUBEの先頭列に出力するかを指定します。 270 * trueが指定された場合はCUBEの先頭列に出力します。 271 * 初期値(false)は合計列を最終列に出力します。 272 * 273 * @og.rev 5.0.0.3 (2009/09/22) 新規追加 274 * 275 * @param firstClmGokei 合計列をCUBEの出力場所[true:先頭列に出力/false:最終列に出力] 276 */ 277 public void setFirstClmGokei( final String firstClmGokei ) { 278 putParam( ViewCrossTableParam.FIRST_CLM_GOKEI_KEY, 279 nval( getRequestParameter( firstClmGokei ),"false" ) ); 280 } 281 282 /** 283 * 【TAG】ヘッダーカラムにレンデラー、エディターを適用するかを指定します(初期値:false)。 284 * 285 * @og.tag 286 * ヘッダーカラムにレンデラー、エディターを適用するかを指定します。 287 * trueが指定された場合は、ヘッダー部分の値そのものをカラム名として扱います。 288 * リソースが存在しない場合は、ラベルのみを各カラムの値で置き換えます。 289 * 初期値(指定無し)は、レンデラー、エディターを適用しない(false)です。 290 * 291 * @og.rev 4.0.0.0 (2007/11/27) 新規追加 292 * @og.rev 5.2.2.0 (2010/11/01) キーに、ViewCrossTableParam.USE_HEADER_COLUMN を使用するように修正 293 * 294 * @param useHeaderColumn ヘッダーカラムにレンデラー、エディターを適用するかどうか 295 */ 296 public void setUseHeaderColumn( final String useHeaderColumn ) { 297// putParam( "useHeaderColumn", 298 putParam( ViewCrossTableParam.USE_HEADER_COLUMN, 299 nval( getRequestParameter( useHeaderColumn ),"false" ) ); 300 } 301 302 /** 303 * 【TAG】各列情報のclass属性に、カラム名などを付与するかどうかを指定します(初期値:false)。 304 * 305 * @og.tag 306 * 列情報の集計列に対して、class 属性を付与するかどうかを指定します。 307 * class属性は、その列のオリジナルの属性名と、ラベル名の文字列を設定します。 308 * 例えば、集計行の計カラムが複数ある場合は、それぞれに色を指定して、ゼブラ模様を 309 * 設定できます。また、ラベル(表示ヘッダー)も設定されるので、特別な列のみ指定することも 310 * 可能になります。 311 * ※ 特殊対応:cssなどで指定できるIDやCLASS属性は、先頭文字が数字の場合は、 312 * 無効になります。(つまり、効きません。) 313 * 表示ヘッダーは、年月や、社員番号(数字)などのケースもあります。そこで、先頭が数字の 314 * 場合は、"x"(小文字のx)を自動的に頭に追加します。この処理は、ViewForm_HTMLCrossTable 315 * で行います。 316 * 317 * @og.rev 5.2.2.0 (2010/11/01) 新規追加 318 * 319 * @param useClassAdd 各列情報のclass属性に、カラム名などを付与するかどうか 320 */ 321 public void setUseClassAdd( final String useClassAdd ) { 322 putParam( ViewCrossTableParam.USE_CLASS_ADD, 323 nval( getRequestParameter( useClassAdd ),"false" ) ); 324 } 325 326 /** 327 * 【TAG】クロス集計結果の DBTableModel をセーブするセッションキーワードを指定します。 328 * 329 * @og.tag 330 * 検索のみの場合は、何も設定しません。EXCEL等外部にクロス集計の形で 331 * 取り出したい場合に、設定します。 332 * "DEFAULT" という文字列を指定すると、内部では、HybsSystem.TBL_MDL_KEY が 333 * 設定されます。(DEFAULT という文字列に設定されるわけではありません。) 334 * なお、DEFAULT を使用する場合は、検索結果の DBTbleModel をつぶすことになります 335 * ので、NEXT 等は使えません。DBTableModel のデータを利用した forward 等も 336 * 使用できませんので、十分ご注意ください。 337 * DEFAULT 以外の文字列の場合は、指定した文字列そのものがキーになります。 338 * 他のセッションキーと同じにすると動作が不安定になりますので、使用する場合は、 339 * "CROSS_TABLE_SAVE_KEY" を推奨致します。 340 * 指定しない場合は、セッションにセーブされません。(検索されたまま) 341 * 通常、EXCEL出力等を行う場合は、DBTableModel をセーブする必要がありますが、 342 * scope="session" にセーブすると、PREV,NEXT が使えなくなります。これは、 343 * クロス集計時に元のカラムが表形式の別のカラムに置き換えられるためです。 344 * scope="request" では、エラーは発生しなくなりますが、外部に取り出せなくなります。 345 * 346 * @og.rev 5.2.2.0 (2010/11/01) キーに、ViewCrossTableParam.SAVE_TABLEID_KEY を使用するように修正 347 * 348 * @param id sessionに登録する時の ID 349 */ 350 public void setSaveTableId( final String id ) { 351 String tableId = nval( getRequestParameter( id ),null ); 352 if( "DEFAULT".equals( tableId ) ) { 353 tableId = HybsSystem.TBL_MDL_KEY; 354 } 355 putParam( ViewCrossTableParam.SAVE_TABLEID_KEY , tableId ); 356// putParam( "saveTableId", tableId ); 357 } 358 359 /** 360 * 【TAG】クロス集計結果の DBTableModel をセーブする scope を指定します。 361 * 362 * @og.tag 363 * スコープは (request,page,session,applicaton) がありますが、request か session が 364 * 通常選択されます。 365 * また、この設定が有効になるには、saveTableId を指定する必要があります。 366 * saveTableId を指定しないと、そもそも書き出されないため、scope は無視されます。 367 * 368 * scope="session" にセーブすると、PREV,NEXT が使えなくなります。これは、 369 * クロス集計時に元のカラムが表形式の別のカラムに置き換えられるためです。 370 * scope="request" では、エラーは発生しなくなりますが、外部に取り出せなくなります。 371 * 何も指定しない場合は、viewタグに指定されたオリジナルのスコープに書き出されます。 372 * そうで無い場合は、指定のスコープに書き出されます。 373 * 374 * @og.rev 5.2.2.0 (2010/11/01) 新規追加 375 * 376 * @param scope scopeに登録する時の キー 377 * @see #setSaveTableId( String ) 378 */ 379 public void setSaveScope( final String scope ) { 380 putParam( ViewCrossTableParam.SAVE_SCOPE_KEY, 381 nval( getRequestParameter( scope ), null ) ); 382 } 383 384 /** 385 * 【TAG】ヘッダーカラムにラベルリソースを利用するかを指定します(初期値:false)。 386 * 387 * @og.tag 388 * HTMLCrossTableViewで、ヘッダーカラムの表示にラベルリソースを利用するかどうかを指定します。 389 * trueが指定された場合は、ヘッダー部の値のラベルで表示します。 390 * 初期値(指定無し)は、利用しない(false)です。 391 * 392 * @og.rev 5.5.5.0 (2012/07/28) 新規追加 393 * 394 * @param useHeaderResource ヘッダーのラベルにリソースを利用するかどうか 395 */ 396 public void setUseHeaderResource( final String useHeaderResource ) { 397// putParam( "useHeaderColumn", 398 putParam( ViewCrossTableParam.USE_HEADER_RSC, 399 nval( getRequestParameter( useHeaderResource ),"false" ) ); 400 } 401 402 /** 403 * 【TAG】ヘッダーのラベルに利用するコードリソースを指定します。 404 * 405 * @og.tag 406 * この値を指定すると上部ヘッダーの表示を対象カラムのコードに対応するラベルで表示します。 407 * カラムリソースがMENUや、DBMENUのようにSelectionを返す形である必要があります。 408 * 初期値はnullです。 409 * 410 * @og.rev 5.5.5.0 (2012/07/28) 新規追加 411 * 412 * @param headerCode コードリソースのキー 413 */ 414 public void setHeaderCodeColumn( final String headerCode ) { 415 putParam( ViewCrossTableParam.HEADER_CODE_KEY, 416 nval( getRequestParameter( headerCode ),null ) ); 417 } 418 419 /** 420 * タグの名称を、返します。 421 * 自分自身のクラス名より、自動的に取り出せないため、このメソッドをオーバーライドします。 422 * 423 * @og.rev 4.0.0.0 (2005/01/31) 新規追加 424 * 425 * @return タグの名称 426 */ 427 @Override 428 protected String getTagName() { 429 return "crossParam" ; 430 } 431 432 /** 433 * シリアライズ用のカスタムシリアライズ書き込みメソッド 434 * 435 * @og.rev 4.0.0.0 (2006/09/31) 新規追加 436 * @serialData 一部のオブジェクトは、シリアライズされません。 437 * 438 * @param strm ObjectOutputStreamオブジェクト 439 * @throws IOException 入出力エラーが発生した場合 440 */ 441 private void writeObject( final ObjectOutputStream strm ) throws IOException { 442 strm.defaultWriteObject(); 443 } 444 445 /** 446 * シリアライズ用のカスタムシリアライズ読み込みメソッド 447 * 448 * ここでは、transient 宣言された内部変数の内、初期化が必要なフィールドのみ設定します。 449 * 450 * @og.rev 4.0.0.0 (2006/09/31) 新規追加 451 * @serialData 一部のオブジェクトは、シリアライズされません。 452 * 453 * @param strm ObjectInputStreamオブジェクト 454 * @see #release2() 455 * @throws IOException シリアライズに関する入出力エラーが発生した場合 456 * @throws ClassNotFoundException クラスを見つけることができなかった場合 457 */ 458 private void readObject( final ObjectInputStream strm ) throws IOException , ClassNotFoundException { 459 strm.defaultReadObject(); 460 } 461}