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.common.HybsSystemException; 020import org.opengion.hayabusa.db.DBTableModel; 021import org.opengion.hayabusa.resource.GUIInfo; 022import org.opengion.fukurou.util.XHTMLTag; 023import org.opengion.fukurou.util.StringUtil; 024 025import static org.opengion.fukurou.util.StringUtil.nval ; 026 027import java.io.ObjectOutputStream; 028import java.io.ObjectInputStream; 029import java.io.IOException; 030 031/** 032 * フレームを作成するHTML拡張タグで、引数の受け渡しが可能です。 033 * 034 * @og.formSample 035 * ●形式:<og:frame src="…" name="…" /> 036 * ●body:なし 037 * 038 * ●Tag定義: 039 * <og:frame 040 * src ○【HTML】フレームに表示するソースファイルを指定します(必須)。 041 * name ○【HTML】フレーム名を指定します(例:QUERY,RESULT,CONTENTS など)(必須)。 042 * changeGamen 【TAG】ソース指定の画面を変更します 043 * keys 【TAG】引数を指定します 044 * dbTable 【TAG】前ページで選択したデータ列の情報を次のページに渡すかどうか[true/false]を指定します(初期値:false) 045 * longdesc 【HTML】フレームに関する詳しい説明のあるURL(lobgdesc)を指定します 046 * marginwidth 【HTML】フレームの左右余白サイズ(marginwidth)を指定します 047 * marginheight 【HTML】フレームの上下余白サイズ(marginheight)を指定します 048 * noresize 【HTML】フレームサイズを変更できないよう(noresize)に指定します 049 * scrolling 【HTML】スクロールバー(scrolling)の表示/非表示[auto/yes/no]を指定します(初期値:auto) 050 * frameborder 【HTML】フレームの境界線(frameborder)の[0:非表示/1:表示]を指定します(初期値:1) 051 * id 【HTML】要素に対して固有の名前(id)をつける場合に設定します 052 * clazz 【HTML】要素に対して class 属性を設定します 053 * title 【HTML】要素に対する補足的情報(title)を設定します 054 * style 【HTML】この要素に対して適用させるスタイルシート(style)を設定します 055 * caseKey 【TAG】このタグ自体を利用するかどうかの条件キーを指定します(初期値:null) 5.7.7.2 (2014/06/20) 056 * caseVal 【TAG】このタグ自体を利用するかどうかの条件値を指定します(初期値:null) 5.7.7.2 (2014/06/20) 057 * caseNN 【TAG】指定の値が、null/ゼロ文字列 でない場合(Not Null=NN)は、このタグは使用されます(初期値:true) 5.7.7.2 (2014/06/20) 058 * caseNull 【TAG】指定の値が、null/ゼロ文字列 の場合は、このタグは使用されます(初期値:true) 5.7.7.2 (2014/06/20) 059 * forceEnc 【TAG】先頭[のデータも強制的にURLエンコードをかけるかどうか指定します。(初期値:false) 060 * debug 【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false) 061 * /> 062 * 063 * ●使用例: 064 * ・一般的な例:フレーム分割する構文は、HTML準拠。リクエスト変数は各フレームまで転送されます。 065 * <frameset> 066 * <og:frame marginheight="2" marginwidth="2" src="query.jsp" name="QUERY" /> 067 * <og:frame marginheight="2" marginwidth="2" src="forward.jsp" name="RESULT" /> 068 * </frameset> 069 * 070 * ・DBTableModel の値(例ではPN)を、取り出して、リクエスト変数として利用します。 071 * 現状では、commonForward タグ の useTableData="true" dbkeys="{@dbkeys}" 属性を利用します。 072 * <frameset> 073 * <og:frame marginheight="2" marginwidth="2" src="query.jsp" name="QUERY" keys="PN" dbTable="true" /> 074 * <og:frame marginheight="2" marginwidth="2" src="forward.jsp" name="RESULT" keys="PN" dbTable="true" /> 075 * </frameset> 076 * 077 * ・changeGamen 属性を利用して、ソース指定の画面を切り替えます。 078 * たとえば、jsp/index.jsp では、GAMENID属性がURLに存在する場合、直接その画面を 079 * 表示させることができます。 080 * <frameset cols="160,*,0" frameborder="1" framespacing="1"> 081 * <og:frame marginheight="2" marginwidth="2" src="menu/menu.jsp" name="MENU" /> 082 * <og:frame marginheight="2" marginwidth="2" src="GE0000/index.jsp" name="CONTENTS" 083 * changeGamen="{@GAMENID}" /> 084 * </frameset> 085 * 086 * @og.group 画面部品 087 * 088 * @version 4.0 089 * @author Kazuhiko Hasegawa 090 * @since JDK5.0, 091 */ 092public class FrameTag extends HTMLTagSupport { 093 //* このプログラムのVERSION文字列を設定します。 {@value} */ 094 private static final String VERSION = "4.2.1.1 (2008/04/30)" ; 095 096 private static final long serialVersionUID = 421120080430L ; 097 098 private String tableId = HybsSystem.TBL_MDL_KEY; 099// private String changeGmn = null; 100 protected String changeGmn = null; // 5.9.1.2 (2015/10/23) 101 private String keys = null; 102 private transient DBTableModel table = null; 103// private boolean dbTable = false; 104 protected boolean dbTable = false; // 5.9.1.2 (2015/10/23) 105 106 protected boolean useForceEnc = false; // 5.10.15.3 (2019/09/27) 強制URLエンコード用 107 108 // 3.5.2.0 (2003/10/20) システムパラメータ の FRAME_UNDER_BAR_REQUEST_KEY_USED を使用。 109 private final boolean UNDER_BAR_KEY_USED = HybsSystem.sysBool( "FRAME_UNDER_BAR_REQUEST_KEY_USED" ); 110 111 /** 112 * タグリブオブジェクトをリリースします。 113 * キャッシュされて再利用されるので、フィールドの初期設定を行います。 114 * 115 * @og.rev 2.0.0.4 (2002/09/27) カスタムタグの release() メソッドを、追加 116 * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。release2() を doEndTag()で呼ぶ。 117 * @og.rev 5.10.15.3 (2019/09/27) forceEnc追加 118 * 119 */ 120 @Override 121 protected void release2() { 122 super.release2(); 123 tableId = HybsSystem.TBL_MDL_KEY; 124 changeGmn = null; // 4.0.0 (2005/02/28) 125 keys = null; 126 table = null; 127 dbTable = false; 128 useForceEnc = false; // 5.10.15.3 (2019/09/27) 129 } 130 131 /** 132 * リンクを作成します。 133 * 134 * @og.rev 3.5.4.0 (2003/11/25) comand="RENEW" 時には、dbTable 属性は、強制的に false とします。 135 * 136 * @return リンクタグ文字列 137 */ 138 @Override 139 protected String makeTag() { 140 if( changeGmn != null ) { set( "src",changeGmn ); } 141 142 String cmd = getRequest().getParameter( "command" ); 143 if( "RENEW".equals( cmd ) ) { dbTable = false; } 144 145 setIdName(); 146 String urlEnc = getUrlEncode(); 147 return XHTMLTag.frame( getAttributes(),urlEnc ); 148 } 149 150 /** 151 * id 属性 / name 属性 セット 152 * 153 * フレーム名は id 属性で登録する(XHTML) 互換性のため、 154 * id 属性と name 属性には同じ値をセットしておく。 155 * 156 * @og.rev 5.9.1.2 (2015/10/23) 継承先のiframeタグで利用するためprivateからprotectedに 157 * 158 */ 159// private void setIdName() { 160 protected void setIdName() { 161 String idno = get( "id" ); 162 String name = get( "name" ); 163 if( idno == null || idno.length() == 0 ) { 164 if( name != null && name.length() > 0 ) { 165 set( "id", name ); 166 } 167 else { 168 String errMsg = "id 属性か name 属性のどちらかは登録してください。"; 169 throw new HybsSystemException( errMsg ); 170 } 171 } 172 else { 173 set( "name", idno ); 174 } 175 } 176 177 /** 178 * keys 属性 を元に、request情報より values の値を取り込む。 179 * 180 * keys属性は キー情報がカンマ区切りになっている為,ばらして 181 * values属性の配列に一つづつ設定していきます。 182 * 183 * @og.rev 2.0.0.2 (2002/09/24) 検索結果の値を取り込めていなかったバグを修正。 184 * @og.rev 2.1.1.1 (2002/11/15) 選択行情報を取り込めていなかったバグを修正。 185 * @og.rev 3.4.0.3 (2003/09/10) DBTableModelへのリクエスト情報をURLに連結しないように変更。 186 * @og.rev 4.0.0.0 (2005/01/31) getParameterRows() を使用するように変更 187 * @og.rev 5.9.1.2 (2015/10/23) 継承先のiframeタグで利用するためprivateからprotectedに 188 * @og.rev 5.10.15.3 (2019/09/27) forceEnc追加 189 * 190 * @return URLエンコードされた文字列 191 */ 192// private String getUrlEncode() { 193 protected String getUrlEncode() { 194 int[] rowNo = getParameterRows(); // 4.0.0 (2005/01/31) 195 int selcount = rowNo.length; // 4.0.0 (2005/01/31) 196 197 String[] key = (String[])StringUtil.enume2Array( getParameterNames(), new String[0] ); 198 String[] dbkey = null; 199 200 int dbcount = 0; 201 202 int recount = 0; 203 for( int i=0; i<key.length; i++ ) { 204 if( isNormalRequestKey( key[i] ) ) { // 3.4.0.3 (2003/09/10) 205 recount++; 206 } 207 } 208 209 if( keys != null && dbTable && selcount > 0 ) { 210 dbkey = StringUtil.csv2Array( keys ); 211 dbcount = dbkey.length; 212 } 213 214 String[] val = new String[ recount + dbcount + selcount ]; 215 String[] keyt = new String[ recount + dbcount + selcount ]; 216 217 int j = 0; 218 for( int i=0; i<key.length; i++ ) { 219 if( isNormalRequestKey( key[i] ) ) { // 3.4.0.3 (2003/09/10) 220 keyt[j] = key[i]; 221 val[j] = getRequestValue( key[i] ); 222 j++; 223 } 224 } 225 226 if( dbTable && dbcount > 0 ) { 227 table = (DBTableModel)getSessionAttribute( tableId ); 228 if( table != null ) { 229 for( int i=0; i<dbcount; i++ ) { 230 keyt[recount + i] = dbkey[i]; 231 val[recount +i] = table.getValue(rowNo[0],table.getColumnNo( dbkey[i] )); 232 } 233 } 234 } 235 236 // 4.0.0 (2005/01/31) selected文字配列をrowNo数字配列に変更 237 for( int i=0; i<selcount; i++ ) { 238 keyt[recount + dbcount + i] = HybsSystem.ROW_SEL_KEY; 239 val[recount + dbcount + i] = String.valueOf( rowNo[i] ); 240 } 241 242 //return XHTMLTag.urlEncode( keyt,val ); 243 return XHTMLTag.urlEncode( keyt,val,"&",useForceEnc ); // 5.10.15.3 (2019/09/27) 244 } 245 246 /** 247 * 【HTML】フレームに表示するソースファイルを指定します。 248 * 249 * @og.tag フレームに表示するソースファイルを指定します。 250 * 251 * @param src ソースファイル 252 */ 253 public void setSrc( final String src ) { 254 set( "src",getRequestParameter( src ) ); 255 } 256 257 /** 258 * 【HTML】フレーム名を指定します(例:QUERY,RESULT,CONTENTS など)。 259 * 260 * @og.tag フレーム名を指定します。 261 * 262 * @param name フレーム名 263 */ 264 public void setName( final String name ) { 265 set( "name",getRequestParameter( name ) ); 266 } 267 268 /** 269 * 【HTML】フレームに関する詳しい説明のあるURL(lobgdesc)を指定します。 270 * 271 * @og.tag lobgdescを指定します。 272 * 273 * @param longdesc 詳しい説明のあるURL 274 */ 275 public void setLongdesc( final String longdesc ) { 276 set( "longdesc",getRequestParameter( longdesc ) ); 277 } 278 279 /** 280 * 【HTML】フレームの左右余白サイズ(marginwidth)を指定します。 281 * 282 * @og.tag フレームの左右余白サイズを指定します。 283 * 284 * @param marginwidth 左右余白サイズ 285 */ 286 public void setMarginwidth( final String marginwidth ) { 287 set( "marginwidth",getRequestParameter( marginwidth ) ); 288 } 289 290 /** 291 * 【HTML】フレームの上下余白サイズ(marginheight)を指定します。 292 * 293 * @og.tag フレームの上下余白サイズを指定します。 294 * 295 * @param marginheight 上下余白サイズ 296 */ 297 public void setMarginheight( final String marginheight ) { 298 set( "marginheight",getRequestParameter( marginheight ) ); 299 } 300 301 /** 302 * 【HTML】フレームサイズを変更できないよう(noresize)に指定します。 303 * 304 * @og.tag フレームサイズを変更できないように指定します。 305 * 306 * @param noresize フレームサイズを変更させない場合は、"noresize" を指定します。 307 */ 308 public void setNoresize( final String noresize ) { 309 String ns = getRequestParameter( noresize ); 310 if( ns != null ) { set( "noresize", "noresize" ); } 311 } 312 313 /** 314 * 【HTML】スクロールバー(scrolling)の表示/非表示[auto/yes/no]を指定します(初期値:auto)。 315 * 316 * @og.tag 317 * auto:必要に応じてスクロールバーを表示(初期値) 318 * yes:常にスクロールバーを表示 319 * no:常にスクロールバーを表示しない 320 * 321 * @param scrolling スクロールバーの表示/非表示[auto:自動/yes:常時表示/no:非表示] 322 */ 323 public void setScrolling( final String scrolling ) { 324 set( "scrolling",getRequestParameter( scrolling ) ); 325 } 326 327 /** 328 * 【HTML】フレームの境界線(frameborder)の[0:非表示/1:表示]を指定します(初期値:1)。 329 * 330 * @og.tag 331 * 0:枠を表示しない 332 * 1:枠を表示する。 333 * 初期値は、1:枠を表示する です。 334 * 335 * @param frameborder フレームの境界線[0:枠非表示/1:枠表示] 336 */ 337 public void setFrameborder( final String frameborder ) { 338 set( "frameborder",getRequestParameter( frameborder ) ); 339 } 340 341 /** 342 * 【TAG】ソース指定の画面を変更します。 343 * 344 * @og.tag 345 * src 指定がデフォルト設定で、changeGamen属性が設定されている 346 * 場合には、この値が優先されます。 347 * changeGamen は、画面IDのみ指定してください。src には、このID+"/index.jsp" が 348 * 追加されます。つまり、changeGamen="{@GAMENID}" という指定をしておけば、 349 * FavoriteLinkTag 等で引数に GAMENID が指定された場合のみ、この属性が有効になり、 350 * src="実画面ID/index.jsp" が指定されたことと同じ結果になります。 351 * 352 * @og.rev 3.1.2.0 (2003/04/07) 画面IDと実画面ディレクトリとの関連見直し(DIRの代りにGAMENIDを推奨) 353 * @og.rev 4.2.1.1 (2008/04/30) 画面切り替えをするのは、アドレスが設定されいる場合に限る 354 * @param src 置換えソース 355 */ 356 public void setChangeGamen( final String src ) { 357 String sc = nval( getRequestParameter( src ),changeGmn ); 358 if( sc != null ) { 359 GUIInfo guiInfo = getGUIInfo( sc ); 360 if( guiInfo != null && guiInfo.getAddress() != null && guiInfo.getAddress().length() > 0 ) { // 見つからない場合は、アクセス不可 361 changeGmn = guiInfo.getRealAddress( "index.jsp" ); 362 } 363 } 364 } 365 366 /** 367 * 【TAG】引数を指定します。 368 * 369 * @og.tag 370 * URL の引数にセットするキーを カンマ区切りでセットします。 371 * 372 * @param key 引数 373 */ 374 public void setKeys( final String key ) { 375 keys = getRequestParameter( key ) ; 376 } 377 378 /** 379 * 【TAG】前ページで選択したデータ列の情報を次のページに渡すかどうか[true/false]を指定します(初期値:false)。 380 * 381 * @og.tag 382 * ただし、1行分のデータのみです。(複数選択時は、最初の1件目) 383 * true:渡す 384 * false:渡さない。 385 * 初期値は、false:渡さない です。 386 * 387 * @param db 選択データを次のページに渡すかどうか[true:渡す/false:渡さない] 388 */ 389 public void setDbTable( final String db ) { 390 dbTable = nval( getRequestParameter( db ),dbTable ); 391 } 392 393 /** 394 * 【TAG】valsの値が[で開始している場合でもURLEncodeを通すかを設定します(初期値:false)。 395 * 396 * @og.tag 397 * テーブルモデルの値の変換のため、通常は先頭が[の場合はエンコードがかかりません。 398 * 強制的にかける場合にtrueにします。 399 * 400 * @og.rev 5.10.15.3 (2019/09/27) forceEnc追加 401 * 402 * @param flg 403 */ 404 public void setForceEnc( final String flg ) { 405 useForceEnc = nval( getRequestParameter( flg ), useForceEnc ); 406 } 407 408 /** 409 * 標準的な リクエスト情報かどうかを判断します。 410 * 411 * これは、引数のキーが、HybsSystem.ROW_SEL_KEY か、 412 * DBTableModel で送信されたキー( キー__番号)形式の場合は 413 * false を返します。 414 * 通常のリクエストキーとして扱いたくない場合の判定に使用します。 415 * 416 * @og.rev 3.4.0.3 (2003/09/10) 新規追加 417 * @og.rev 3.5.2.0 (2003/10/20) システムパラメータ の FRAME_UNDER_BAR_REQUEST_KEY_USED を使用。 418 * @og.rev 3.5.5.0 (2004/03/12) 名前と行番号の区切り記号("__")を、HybsSystem.JOINT_STRING に変更。 419 * @og.rev 5.9.1.2 (2015/10/23) iframeタグで利用のためprotected化 420 * 421 * @param key 判定するキー 422 * 423 * @return 標準的な リクエスト情報かどうか [true:標準的/false:それ以外] 424 */ 425// private boolean isNormalRequestKey( final String key ) { 426 protected boolean isNormalRequestKey( final String key ) { 427 return key != null && 428 ! key.equals( HybsSystem.ROW_SEL_KEY ) && 429 ( key.indexOf( HybsSystem.JOINT_STRING ) < 0 || UNDER_BAR_KEY_USED ); 430 } 431 432 /** 433 * シリアライズ用のカスタムシリアライズ書き込みメソッド 434 * 435 * @og.rev 4.0.0.0 (2006/09/31) 新規追加 436 * @og.rev 5.9.1.2 (2015/10/23) iframeタグで利用のためprotected化 437 * @serialData 一部のオブジェクトは、シリアライズされません。 438 * 439 * @param strm ObjectOutputStreamオブジェクト 440 * @throws IOException シリアライズに関する入出力エラーが発生した場合 441 */ 442// private void writeObject( final ObjectOutputStream strm ) throws IOException { 443 protected void writeObject( final ObjectOutputStream strm ) throws IOException { 444 strm.defaultWriteObject(); 445 } 446 447 /** 448 * シリアライズ用のカスタムシリアライズ読み込みメソッド 449 * 450 * ここでは、transient 宣言された内部変数の内、初期化が必要なフィールドのみ設定します。 451 * 452 * @og.rev 4.0.0.0 (2006/09/31) 新規追加 453 * @og.rev 5.9.1.2 (2015/10/23) iframeタグで利用のためprotected化 454 * @serialData 一部のオブジェクトは、シリアライズされません。 455 * 456 * @param strm ObjectInputStreamオブジェクト 457 * @see #release2() 458 * @throws IOException シリアライズに関する入出力エラーが発生した場合 459 * @throws ClassNotFoundException クラスを見つけることができなかった場合 460 */ 461// private void readObject( final ObjectInputStream strm ) throws IOException , ClassNotFoundException { 462 protected void readObject( final ObjectInputStream strm ) throws IOException , ClassNotFoundException { 463 strm.defaultReadObject(); 464 } 465 466 /** 467 * このオブジェクトの文字列表現を返します。 468 * 基本的にデバッグ目的に使用します。 469 * 470 * @return このクラスの文字列表現 471 */ 472 @Override 473 public String toString() { 474 return org.opengion.fukurou.util.ToString.title( this.getClass().getName() ) 475 .println( "VERSION" ,VERSION ) 476 .println( "tableId" ,tableId ) 477 .println( "changeGmn" ,changeGmn ) 478 .println( "keys" ,keys ) 479 .println( "dbTable" ,dbTable ) 480 .println( "Other..." ,getAttributes().getAttribute() ) 481 .fixForm().toString() ; 482 } 483}