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.fukurou.util.ErrorMessage; 022import org.opengion.fukurou.util.XHTMLTag; 023import org.opengion.fukurou.util.StringUtil; 024import org.opengion.fukurou.util.ToString; // 6.1.1.0 (2015/01/17) 025 026import static org.opengion.fukurou.util.StringUtil.nval ; 027 028import javax.servlet.http.HttpServletRequest; 029import javax.servlet.http.HttpServletResponse; 030import javax.servlet.http.HttpSession; 031import javax.servlet.ServletException; 032import java.io.IOException; 033import java.util.Enumeration; 034import java.util.Map; 035import java.util.HashMap; 036import java.util.concurrent.ConcurrentMap; // 6.4.3.3 (2016/03/04) 037import java.util.concurrent.ConcurrentHashMap; // 6.4.3.1 (2016/02/12) refactoring 038 039/** 040 * submitタグを用いてページ転送するタグです(forward.jsp で使用)。 041 * 042 * 通常、forward は、ページ内転送(サーバー内部での転送)のため、別画面への遷移には 043 * 使用できません。これは、別画面では、index.jsp 等でフレーム分割する際の基準フォルダは、 044 * forward の場合、クライアントは理解していないため、もう一度先のフォルダに対する 045 * フレーム分割を行おうとするためです。 046 * (よく、index.jsp の frame タグに、src="../XXXX/query.jsp" などと、自分自身のフォルダ名を 047 * 記述したページを見かけますが、これは、フォルダをまたがる転送に、forward を使用する 048 * 為の悪い対策です。) 049 * 実際は、forward ではなく、redirect を使うべきです。redirect は、指定のアドレス要求を、 050 * 一旦クライアントに投げてそこから再度要求しなおしてもらう方式のため、このようにフォルダを 051 * またがる転送も正常に処理できます。 052 * この、commonForward タグでは、画面遷移の条件に応じて、forward か redirect の自動 053 * 判定を行い、適切に処理しています。 054 * 判定条件は、拡張子や、選択件数などを加味して以下の判定を順次テストします。 055 * 056 * FORWARD : 057 * アドレスが、 null(自分自身) か、.jsp を含み、"/" が入っていない場合 058 * REDIRECT: 059 * アドレスが、.jsp を含まないか、 060 * それ以外(.jsp を含み、"/" も含む)で、選択数が1件のみの場合 061 * もしくはuseRedirectCheck="false"の場合 062 * COUNT_0 : 063 * それ以外で、選択数が0件の場合 064 * COUNT_N : 065 * それ以外で、選択数が1件以上の場合、または、その他。 066 * 067 * ここで、COUNT_0 の場合は、未選択エラー、COUNT_N は、複数選択エラーを自動的に返します。 068 * 069 * @og.formSample 070 * ●形式:<og:commonForward /> 071 * ●body:なし 072 * 073 * ●Tag定義: 074 * <og:commonForward 075 * dbkeys 【TAG】DBキーをCSV形式でセットします 076 * tableId 【TAG】(通常は使いません)sessionから所得する DBTableModelオブジェクトの ID 077 * useRedirectCheck 【TAG】非選択状態の場合にforwardを許可するかどうか[true/false]を指定します(初期値:true) 078 * useRedirectHidden 【TAG】redirectの処理時に、hiddenパラメータを転送するかどうか[true:する/false:しない]指定します(初期値:false)。 079 * debug 【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false) 080 * useSLabel 【TAG】7.0.7.0 (2019/12/13) エラーメッセージにSLABELを利用するかどうか[true/false]を指定します(初期値:false) 081 * /> 082 * 083 * ●使用例 084 * フォワードキャッシュによりページ転送します。 085 * <og:commonForward dbkeys="{@dbkeys}" /> 086 * 087 * @og.group 画面制御 088 * 089 * @version 4.0 090 * @author Masaharu Endo 091 * @since JDK5.0, 092 */ 093public class CommonForwardTag extends CommonTagSupport { 094 /** このプログラムのVERSION文字列を設定します。 {@value} */ 095 private static final String VERSION = "7.0.7.0 (2019/12/13)" ; 096 private static final long serialVersionUID = 707020191213L ; 097 098 // 3.5.5.3 (2004/04/09) 共通アドレスで指定することで、クライアントキャッシュを有効利用する。 099 private static final String DUMMY_HTML = "/" + HybsSystem.getContextName() + "/jsp/common/dummy.html"; 100 101 // 3.8.5.1 (2006/04/28) dbkeys が null の場合に全件取得するかどうかを COMMON_FORWARD_DBKEYS_NULL_ALL で指定します。 102 103 private static final int FORWARD = 0; 104 private static final int REDIRECT = 1; 105 private static final int COUNT_0 = 2; 106 private static final int COUNT_N = 3; 107 108 // 3.5.5.2 (2004/04/02) 選択行が、1行のみか、そうでないか 109 private int rowCount = -1; 110 111 private int rowNo = -1; 112 113 // 3.5.5.5 (2004/04/23) URLに連結するDBTableModelのカラムをCSV形式で指定します。 114 private String dbkeys ; 115 116 // 3.5.5.8 (2004/05/20) submitタグの keys,vals を扱う 仮想リクエストMap 117 private String tableIdTemp ; 118 private String dbkeysTemp ; 119 /** 6.4.3.1 (2016/02/12) PMD refactoring. HashMap → ConcurrentHashMap に置き換え。 */ 120 private final transient ConcurrentMap<String,String> submitRequestMap = new ConcurrentHashMap<>(); 121 /** 6.4.3.1 (2016/02/12) PMD refactoring. HashMap → ConcurrentHashMap に置き換え。 */ 122 private final transient ConcurrentMap<String,String> submitTableMap = new ConcurrentHashMap<>(); 123 124 // 4.0.0.0 (2007/11/09) 非選択状態でのforwardのための属性追加 125 private boolean isRedirectCheck = true; 126 127 // 6.2.4.0 (2015/05/15) redirectの処理時に、hiddenパラメータを転送するかどうか[true:する/false:しない] 128 // 互換性の関係で、初期値は、false にします。 129 private boolean isRedirectHidden ; 130 131 // 7.0.7.0 (2019/12/13) エラーメッセージにSLABELを利用するかどうか[true/false]を指定します(初期値:false) 132 private boolean useSLabel ; 133 134 /** 135 * デフォルトコンストラクター 136 * 137 * @og.rev 6.4.2.0 (2016/01/29) PMD refactoring. Each class should declare at least one constructor. 138 */ 139 public CommonForwardTag() { super(); } // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。 140 141 /** 142 * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。 143 * 144 * @og.rev 3.3.1.1 (2003/07/03) URLにリクエスト情報をURLエンコードして追加します。 145 * @og.rev 3.5.5.2 (2004/04/02) フォルダ外転送時は、1行以外選択は、エラーとします。 146 * @og.rev 3.5.5.3 (2004/04/09) デバッグ時は、転送しないようにします。 147 * @og.rev 3.8.0.4 (2005/08/08) requestUrlEncode 廃止 148 * @og.rev 3.8.0.8 (2005/10/03) dbkeys が null の場合に全件取得していた処理を復活します。 149 * @og.rev 4.0.0.0 (2007/11/09) 非選択状態からの遷移を許可するフラグを追加(11/12に振り分け処理をselectResponseMethodに移動) 150 * @og.rev 5.0.0.2 (2009/09/15) XSS対応⇒チェックする 151 * @og.rev 5.3.6.0 (2011/06/01) エラーメッセージ変更(URLの振り分け処理時に...のメッセージは出力しない) 152 * @og.rev 6.2.4.0 (2015/05/15) useRedirectHidden 属性追加 153 * @og.rev 7.0.7.0 (2019/12/13) useSLabel 属性を追加。 154 * 155 * @return 後続処理の指示 156 */ 157 @Override 158 public int doEndTag() { 159 debugPrint(); // 4.0.0 (2005/02/28) 160 161 // useXssCheck( false ); // 5.0.0.2 (2009/09/15) 162 163 final HttpServletRequest request = ((HttpServletRequest)getRequest()); 164 final HttpSession session = pageContext.getSession(); 165 String page = getForwardURI( request, session ); 166 167 // 3.5.5.8 (2004/05/20) 内部仮想リクエストMap より値を取得 168 dbkeys = nval( getSubmitRequestParameter( dbkeysTemp ),dbkeys ); 169 170 final HttpServletResponse response = (HttpServletResponse)pageContext.getResponse(); 171 172 String errMsgKey = null; 173 try { 174 175 // 3.8.0.8 (2005/10/03) dbkeys が null の場合に全件取得していた処理を復活します。 176 // 6.2.4.0 (2015/05/15) dbkeys != null の場合しか、[]付のパラメータを処理できなかった。 177 if( rowCount == 1 && ( dbkeys != null || !submitTableMap.isEmpty() ) ) { // 6.3.9.0 (2015/11/06) size() == 0 判定は、isEmpty() に置き換え可能 178 page = XHTMLTag.addUrlEncode( page,getTableUrlData() ); 179 } 180 181 final String url = response.encodeRedirectURL( page ); 182 // 3.8.0.8 (2005/10/03) GET時の URL の長さ制限チェック(最大文字数は 2,083 文字) 183 if( url != null && url.length() >= HybsSystem.MAX_GET_LENGTH ) { 184 final String errMsg = "GET時の URL の長さは,最大2,083 文字です。" 185 + " URL.length=" + url.length() + " , MAX_LENGTH=" + HybsSystem.MAX_GET_LENGTH ; 186 throw new HybsSystemException( errMsg ); 187 } 188 189 // 6.4.9.1 (2016/08/05) Avoid declaring a variable if it is unreferenced before a possible exit point. 190 final int flag = selectResponseMethod( page ); 191 switch( flag ) { 192 case FORWARD: if( isDebug() ) { jspPrint( "FORWARD URL = [" + url + "]" ); } 193 else { pageContext.forward( url ); } 194 break; 195 case REDIRECT: // url = requestUrlEncode( url ); // 3.8.0.4 (2005/08/08) 196 if( isDebug() ) { jspPrint( "REDIRECT URL = [" + url + "]" ); } 197 else { response.sendRedirect( url ); } 198 break; 199 case COUNT_0: 200 errMsgKey = "ERR0028" ; // 選択されていません。もう一度、選択しなおして下さい。 201 break; 202 default: errMsgKey = "ERR0029" ; // 複数選択されました。1件のみ選択しなおして下さい。 203 break; 204 } 205 } catch( final IOException ex ) { 206 // 5.3.6.0 (2011/06/01) エラーメッセージ表示変更 207 final String errMsg = ex.getMessage(); // 5.1.8.0 (2010/07/01) errMsg 修正 208 throw new HybsSystemException( errMsg,ex ); // 3.5.5.4 (2004/04/15) 引数の並び順変更 209 } catch( final ServletException ex ) { 210 // 5.3.6.0 (2011/06/01) エラーメッセージ表示変更 211 final String errMsg = ex.getMessage(); // 5.1.8.0 (2010/07/01) errMsg 修正 212 throw new HybsSystemException( errMsg,ex ); // 3.5.5.4 (2004/04/15) 引数の並び順変更 213 } 214 215 // 3.5.5.2 (2004/04/02) フォルダ外転送時は、1行以外選択は、エラーとします。 216 if( errMsgKey != null ) { 217 final ErrorMessage errMsg = new ErrorMessage( "Row Count Error Maximal Error!" ); 218 errMsg.addMessage( 0,ErrorMessage.NG,errMsgKey ); 219 220// jspPrint( TaglibUtil.makeHTMLErrorTable( errMsg,getResource() ) ); 221 jspPrint( TaglibUtil.makeHTMLErrorTable( errMsg,getResource(),useSLabel ) ); // 7.0.7.0 (2019/12/13) 222 } 223 224 return SKIP_PAGE ; // ページの残りの処理を行わない。 225 } 226 227 /** 228 * タグリブオブジェクトをリリースします。 229 * キャッシュされて再利用されるので、フィールドの初期設定を行います。 230 * 231 * @og.rev 3.5.5.2 (2004/04/02) 新規追加(rowCount,useTableData) 232 * @og.rev 3.5.5.5 (2004/04/23) URLに連結するDBTableModelのカラムをCSV形式で指定します。 233 * @og.rev 3.8.5.1 (2006/04/28) URLに連結するDBTableModelのカラムを[カラム]形式で指定します。 234 * @og.rev 6.2.4.0 (2015/05/15) useRedirectHidden 属性追加 235 * @og.rev 6.4.3.1 (2016/02/12) PMD refactoring. HashMap → ConcurrentHashMap に置き換え。 236 * @og.rev 7.0.7.0 (2019/12/13) useSLabel 属性を追加。 237 */ 238 @Override 239 protected void release2() { 240 super.release2(); 241 rowCount = -1; 242 rowNo = -1; 243 dbkeys = null; // 3.5.5.5 (2004/04/23) 244 submitRequestMap.clear(); // 6.4.3.3 (2016/03/04) 245 submitTableMap.clear(); // 6.4.3.3 (2016/03/04) 246 tableIdTemp = null; // 3.5.5.8 (2004/05/20) 247 dbkeysTemp = null; // 3.5.5.8 (2004/05/20) 248 isRedirectCheck = true; // 4.0.0.0 (2007/11/12) 249 isRedirectHidden = false; // 6.2.4.0 (2015/05/15) 250 useSLabel = false; // 7.0.7.0 (2019/12/13) エラーメッセージにSLABELを利用するかどうか[true/false]を指定します(初期値:false) 251 } 252 253 /** 254 * フォワード先URIを取得します。 255 * 256 * @og.rev 3.1.2.0 (2003/04/07) ソースコード中の固定値を、定義ファイルを使用するように変更する。 257 * @og.rev 3.1.4.1 (2003/04/21) request.getQueryString() をaddUrlEncodeしている箇所を削除。 258 * @og.rev 3.1.7.0 (2003/05/02) コマンド RENEW で、forward した場合に、result.jsp に遷移するように修正。 259 * @og.rev 3.1.7.0 (2003/05/02) 画面IDのセットで、自画面を、BACK_GAMENID 、飛び先を、GAMENID にする。 260 * @og.rev 3.1.8.0 (2003/05/16) SubmitData クラスを利用するように変更。 261 * @og.rev 3.3.1.1 (2003/07/03) ForwardManager クラスの廃止。飛び先のキャッシュを廃止します。 262 * @og.rev 3.5.5.2 (2004/04/02) 選択行の件数を設定しておきます。 263 * @og.rev 3.5.5.3 (2004/04/09) dummy.html を static final で絶対パス指定します。 264 * @og.rev 3.5.5.4 (2004/04/15) メソッド内で使用していない、gamenId,jspID 変数を削除します。 265 * @og.rev 3.5.5.5 (2004/04/23) 余計なボタン関連情報を転送しない為に、キーを変更します。 266 * @og.rev 3.5.5.5 (2004/04/23) SubmitTag の keys,vals 属性で指定した値のみ、転送します。 267 * @og.rev 3.5.5.8 (2004/05/20) SubmitTag の keys,vals 属性で指定した値を、内部仮想リクエスト Mapにセットします。 268 * @og.rev 3.7.0.1 (2005/01/31) リクエスト変数に選択された件数を追加 269 * @og.rev 3.7.0.3 (2005/03/01) 指定の行番号まで画面をスクロールさせる機能を追加。 270 * @og.rev 3.8.0.8 (2005/10/03) BACK_GAMENID があれば BACK_ROW を追加する。 271 * @og.rev 3.8.5.1 (2006/04/28) vals="[カラム名]" という引数を処理できる機能を追加。 272 * @og.rev 5.1.8.0 (2010/07/01) VIEWの場合も、直前のJSPに遷移する。 273 * @og.rev 6.2.4.0 (2015/05/15) useRedirectHidden 属性追加 274 * @og.rev 6.4.3.1 (2016/02/12) PMD refactoring. HashMap → ConcurrentHashMap に置き換え。 275 * @og.rev 6.4.5.2 (2016/05/06) UPLOADから呼ばれた場合は、RESET は、command="RENEW" , displayMsg=" " にします。 276 * 277 * @param request HttpServletRequestオブジェクト 278 * @param session HttpSessionオブジェクト 279 * 280 * @return フォワード先URI 281 * @og.rtnNotNull 282 */ 283 private String getForwardURI( final HttpServletRequest request, 284 final HttpSession session ) { 285 286 final String[] rows = request.getParameterValues( HybsSystem.ROW_SEL_KEY ); 287 288 // 4.0.0 (2007/05/16) query.jsp で複数command 時の処理修正 289 String cmd = request.getParameter( "command" ); 290 final String[] cmds = request.getParameterValues( "command" ); 291 if( cmds != null && cmds.length > 1 ) { 292 for( int i=0; i<cmds.length; i++ ) { 293 if( ! "NEW".equals( cmds[i] ) ) { 294 cmd = cmds[i]; break; // NEW でない、最初の一つ 295 } 296 } 297 // すべてが NEW の場合は、単体(getParameter) が NEW なので素通りでよい。 298 } 299 300 // 3.5.5.2 (2004/04/02) 選択行の件数 301 // 6.4.1.1 (2016/01/16) PMD refactoring. Avoid if (x != y) ..; else ..; 302 if( rows == null ) { 303 rowCount = 0; 304 } 305 else { 306 rowCount = rows.length; 307 rowNo = Integer.parseInt( rows[0] ); 308 } 309 // 3.7.0.1 (2005/01/31) リクエスト変数に選択された件数を追加 310 setRequestAttribute( "ROW_COUNT",String.valueOf( rowCount ) ); 311 312 if( cmd == null || cmd.isEmpty() ) { cmd = "INIT"; } 313 final String forwardPage; 314 315 final String backPage = (String)session.getAttribute( HybsSystem.FORWARD_PAGE_KEY ); 316 String command = cmd; // 3.5.5.5 (2004/04/23) 317 int pagePlus = 0; 318 319 // コマンドパラメータにより振分け 320 // 5.1.8.0 (2010/07/01) VIEWの場合も、直前のJSPに遷移する。 321 if( "FIRST,PREV,NEXT,LAST,VIEW".indexOf( cmd ) >= 0 ) { 322 forwardPage = backPage; 323 } else if( "NEW,RENEW".indexOf( cmd ) >= 0 ) { 324 // 初期値 325 forwardPage = "result.jsp"; 326 } else if( "INIT".equals( cmd ) ) { 327 forwardPage = DUMMY_HTML; // 3.5.5.3 (2004/04/09) 328 } else { 329 // 共有オブジェクト検索 330 331 // リンク元コマンド名取得 332 // 3.5.5.5 (2004/04/23) 余計なボタン関連情報を転送しない為に、キーを変更します。 333 command = request.getParameter( HybsSystem.NO_XFER_KEY + cmd + "CMD" ); 334 335 // 3.7.0.3 (2005/03/01) 指定の行番号まで画面をスクロールさせる機能を追加。 336 if( rows != null && "ENTRY".equals( command ) ) { 337 setRequestCacheData( "SEL_ROW",String.valueOf( rowNo ) ); 338 } 339 340 if( "RESET".equals( command ) ) { // RESET 時 341 forwardPage = "result.jsp"; 342 343 // 6.4.5.2 (2016/05/06) UPLOADから呼ばれた場合は、RESET は、command="RENEW" , displayMsg=" " にします。 344 if( Boolean.parseBoolean( request.getParameter( HybsSystem.USE_UPLOAD_KEY ) ) ) { 345 command = "RENEW"; 346 setRequestAttribute( "displayMsg"," " ); // RESETなので、メッセージは出さない。 347 setRequestCacheData( "SEL_ROW" ,null ); // RENEWで戻るため、以前に行選択があったら、そこに戻ってしまうため、クリアしておく。 348 } 349 } 350 else { 351 // リンク先取得 352 forwardPage = request.getParameter( HybsSystem.NO_XFER_KEY + cmd ); 353 // INSERTとCOPYの場合のみ 354 if( "INSERT".equals( command ) || "COPY".equals( command ) ) { 355 if( rows != null ) { pagePlus = rows.length; } 356 } 357 } 358 } 359 360 if( ! forwardPage.equals( backPage ) ) { 361 session.setAttribute( HybsSystem.REVIEW_PAGE_KEY , backPage ); 362 } 363 session.setAttribute( HybsSystem.FORWARD_PAGE_KEY, forwardPage ); 364 365 // 3.5.5.5 (2004/04/23) SubmitTag の keys,vals 属性で指定した値のみ、転送します。 366 // 6.0.2.5 (2014/10/31) char を append する。 367 final StringBuilder strURL = new StringBuilder( BUFFER_MIDDLE ) 368 .append( '&' ).append( "command" ).append( '=' ).append( command ) 369 .append( '&' ).append( "pagePlus" ).append( '=' ).append( String.valueOf( pagePlus ) ); 370 371 final String btnKey = HybsSystem.NO_XFER_KEY + cmd + "KEY_" ; 372 final int keylen = btnKey.length() ; 373 374 final Enumeration<?> enm = getParameterNames(); // 4.3.3.6 (2008/11/15) Generics警告対応 375 376 // 6.2.4.0 (2015/05/15) useRedirectHidden 属性追加 377 final Map<String,String> hiddenMap = new HashMap<>(); 378 boolean isGamenIdFlag = false; 379 380 while( enm.hasMoreElements() ) { 381 final String key = (String)( enm.nextElement() ); 382 // 3.5.5.5 (2004/04/23) 余計な情報を転送しない様に、キーを選別します。 383 if( key != null && key.startsWith( btnKey ) ) { 384 // 3.5.5.8 (2004/05/20) 内部の仮想リクエスト Map に設定します。 385 final String kk = key.substring( keylen ) ; 386 final String vv = nval( getRequestValue( key ) , "" ); // 6.4.3.1 (2016/02/12) ConcurrentHashMap の条件は、key,val ともに、not null 387 // 3.8.5.1 (2006/04/28) vals="[カラム名]" という引数を処理できる機能を追加。 388 if( vv.length() > 2 && vv.charAt(0) == '[' && vv.charAt(vv.length()-1) == ']' ) { 389 submitTableMap.put( kk,vv.substring( 1,vv.length()-1 )); 390 } 391 // else if( "dbkeys".equals( kk ) ) { 392 // submitRequestMap.put( kk,vv ); 393 // } 394 else { 395 submitRequestMap.put( kk,vv ); 396 strURL.append( '&' ) // 6.0.2.5 (2014/10/31) char を append する。 397 .append( kk ).append( '=' ) // 6.0.2.5 (2014/10/31) char を append する。 398 .append( StringUtil.urlEncode( vv ) ); 399 } 400 401 // 3.8.0.8 (2005/10/03) BACK_GAMENID があれば BACK_ROW を追加する。 402 if( "BACK_GAMENID".equalsIgnoreCase( kk ) && rowNo >= 0 ) { 403 strURL.append( "&BACK_ROW=" ).append( rowNo ); 404 } 405 406 // 6.2.4.0 (2015/05/15) 個別に GAMENID があれば、submitTag で指定されたはず。 407 if( "GAMENID".equalsIgnoreCase( kk ) ) { 408 isGamenIdFlag = true; 409 } 410 } 411 // 6.2.4.0 (2015/05/15) useRedirectHidden 属性追加 412 // 取りあえず対象のリクエストは、Mapにセットしておきます。 413 if( isRedirectHidden && key != null && !key.startsWith( "h_" ) && !key.startsWith( "hX_" ) ) { 414 hiddenMap.put( key,getRequestValue( key,false ) ); 415 } 416 } 417 418 // 6.2.4.0 (2015/05/15) useRedirectHidden 属性追加 419 // 個別に GAMENID がある場合(isGamenIdFlag == true)のみ、このフラグを有効にします。 420 if( isRedirectHidden && isGamenIdFlag ) { 421 for( final Map.Entry<String,String> entry : hiddenMap.entrySet() ) { 422 final String key = '&' + entry.getKey() + '='; // strURL は、必ず & で始まっている。 423 if( strURL.indexOf( key ) < 0 ) { // すでに、個別定義済みのパラメータは転送しない。 424 strURL.append( key ).append( StringUtil.urlEncode( entry.getValue() ) ); 425 } 426 } 427 } 428 429 return XHTMLTag.addUrlEncode( forwardPage,strURL.toString() ); 430 } 431 432 /** 433 * ページを リダイレクトかフォワードか選択します。 434 * 判定条件は、拡張子や、選択件数などを加味して以下の判定を順次テストします。 435 * 436 * FORWARD : 437 * アドレスが、 null か、.jsp を含み、"/" が入っていない場合 438 * REDIRECT: 439 * アドレスが、.jsp を含まないか、それ以外(.jsp を含み、"/" も含む)で、選択数が1件のみの場合 440 * COUNT_0 : 441 * それ以外で、選択数が0件の場合 442 * COUNT_N : 443 * それ以外で、選択数が1件以上の場合、または、その他。 444 * 445 * @og.rev 3.5.5.2 (2004/04/02) 新規作成:isJspPrefix( String page ) の代用です。 446 * @og.rev 4.0.0.0 (2007/05/23) useTableData の書き換えを中止します。 447 * @og.rev 4.0.0.0 (2007/11/12) 非選択状態でもリダイレクト可能なフラグ(isRedirectCheck)を追加 448 * 449 * @param page 判定する転送先アドレス 450 * 451 * @return FORWARD,REDIRECT,COUNT_0,COUNT_N のうち、どれか 452 */ 453 private int selectResponseMethod( final String page ) { 454 if( page == null ) { return FORWARD; } 455 456 final int adrs = page.indexOf( ".jsp" ); 457 458 if( adrs >= 0 && page.lastIndexOf( '/',adrs ) < 0 ) { 459 return FORWARD; 460 } 461 else if( adrs < 0 || !isRedirectCheck ) { // 4.0.0.0 (2007/11/12) 非選択リダイレクト許可フラグ追加 462 return REDIRECT; 463 } 464 else if( rowCount == 1 ) { 465 return REDIRECT; 466 } 467 else if( rowCount == 0 ) { 468 return COUNT_0; 469 } 470 else { 471 return COUNT_N; 472 } 473 } 474 475 /** 476 * 【TAG】(通常は使いません)sessionから所得する DBTableModelオブジェクトの ID 477 * (初期値:HybsSystem#TBL_MDL_KEY[={@og.value HybsSystem#TBL_MDL_KEY}])。 478 * 479 * @og.tag 480 * 表示処理後に,(内部ポインタを書き換えた)DBTableModelオブジェクトを 481 * 同じキーで、sessionに登録します。 482 * (初期値:HybsSystem#TBL_MDL_KEY[={@og.value HybsSystem#TBL_MDL_KEY}])。 483 * 484 * @og.rev 3.5.5.2 (2004/04/02) 新規追加 485 * @og.rev 3.5.5.8 (2004/05/20) 内部仮想リクエスト Map を参照できるようにする。 486 * 487 * @param id テーブルID (sessionから所得する時のID) 488 */ 489 public void setTableId( final String id ) { 490 // 注意:引数のリクエスト変数が無ければ、自分自身({@XXX}形式)を再セットする。 491 tableIdTemp = nval( getRequestParameter( id ),id ); 492 } 493 494 /** 495 * 指定のスコープの内部キャッシュ情報に、DBTableModel の選択された値を登録します。 496 * 497 * 複数選択行が存在する場合は、先頭行を処理します。ただし、action="APPEND"の 498 * 場合は、separator属性で指定された文字を使用して、連結します。 499 * 500 * @og.rev 3.5.5.2 (2004/04/02) 新規作成 501 * @og.rev 3.5.5.5 (2004/04/23) URLに連結するDBTableModelのカラムをCSV形式で指定します。 502 * @og.rev 3.8.0.4 (2005/08/08) dbkeys が null の場合に全件取得していた処理を中止します。 503 * @og.rev 3.8.0.8 (2005/10/03) dbkeys が null の場合に全件取得していた処理を復活します。 504 * @og.rev 3.8.5.1 (2006/04/28) vals="[カラム名]" という引数を処理できる機能を追加。 505 * @og.rev 3.8.5.1 (2006/04/28) dbkeys が null の場合に全件取得するかどうかを COMMON_FORWARD_DBKEYS_NULL_ALL で指定します。 506 * @og.rev 4.0.0.0 (2007/05/23) tableId をこのメソッド内で求めます。 507 * 508 * @return DBTableModelの選択された値の文字列 509 * @og.rtnNotNull 510 */ 511 private String getTableUrlData() { 512 final String tableId = nval( getSubmitRequestParameter( tableIdTemp ),HybsSystem.TBL_MDL_KEY ); 513 514 final DBTableModel table = (DBTableModel)getSessionAttribute( tableId ); 515 516 String dbkeysUrl = ""; 517 String tblkeysUrl = ""; 518 519 if( table != null ) { 520 String[] keys = null; 521 String[] vals = null; 522 if( dbkeys != null ) { 523 keys = StringUtil.csv2Array( dbkeys ); 524 vals = new String[keys.length]; 525 for( int i=0; i<keys.length; i++ ) { 526 final int clmNo = table.getColumnNo( keys[i] ); 527 vals[i] = table.getValue(rowNo,clmNo); 528 } 529 } 530 531 dbkeysUrl = XHTMLTag.urlEncode( keys, vals ); 532 533 // 3.8.5.1 (2006/04/28) vals="[カラム名]" という引数を処理できる機能を追加。 534 final int size = submitTableMap.size(); 535 if( size > 0 ) { 536 @SuppressWarnings("rawtypes") 537 final Map.Entry[] entry = submitTableMap.entrySet().toArray( new Map.Entry[size] ); 538 539 String[] tblkeys = new String[size]; 540 String[] tblvals = new String[size]; 541 542 for( int i=0; i<size; i++ ) { 543 tblkeys[i] = (String)entry[i].getKey(); 544 final String temp = (String)entry[i].getValue(); 545 final int clmNo = table.getColumnNo( temp ); 546 tblvals[i] = table.getValue( rowNo,clmNo ); 547 } 548 tblkeysUrl = XHTMLTag.urlEncode( tblkeys, tblvals ); 549 } 550 } 551 552 String rtn = dbkeysUrl; 553 554 if( tblkeysUrl.length() > 0 ) { 555 if( rtn.length() > 0 ) { 556 rtn += "&" + tblkeysUrl; 557 } 558 else { 559 rtn = tblkeysUrl ; 560 } 561 } 562 return rtn ; 563 } 564 565 /** 566 * 【TAG】DBキーをCSV形式でセットします。 567 * 568 * @og.tag 569 * URI の引数にセットするキーを CSV形式でセットします。 570 * ここの指定は,DBTableModel 上のデータを取り込みます。 571 * 572 * @og.rev 3.5.5.5 (2004/04/23) URLに連結するDBTableModelのカラムをCSV形式で指定します。 573 * @og.rev 3.5.5.8 (2004/05/20) 内部仮想リクエスト Map を参照できるようにする。 574 * 575 * @param key DBキー(CSV形式) 576 */ 577 public void setDbkeys( final String key ) { 578 // 注意:引数のリクエスト変数が無ければ、自分自身({@XXX}形式)を再セットする。 579 dbkeysTemp = nval( getRequestParameter( key ),key ) ; 580 } 581 582 /** 583 * 内部の仮想リクエスト Map より、リクエストパラメータより値を設定します。 584 * 585 * submitタグの keys,vals より送信されたリクエスト値は、このクラスで 586 * 処理され、内部の仮想リクエスト Map に保存されます。 587 * 通常のリクエスト設定時点では、この値は取り出すことが出来ない為、 588 * Map に保存(getForwardURI 処理で設定)された後に、引き出します。 589 * 590 * @og.rev 3.5.5.8 (2004/05/20) 新規作成 591 * 592 * @param key DBキー(CSV形式) 593 * 594 * @return 仮想リクエスト Map を反映させた、リクエスト値 595 */ 596 private String getSubmitRequestParameter( final String key ) { 597 String rtn = key; 598 599 // 変数が "{@XXXX}" の場合のみ対応 600 if( key != null && key.startsWith( "{@" ) && key.charAt(key.length()-1) == '}' ) { 601 rtn = submitRequestMap.get( key.substring( 2,key.length()-1 ) ); 602 } 603 604 return rtn; 605 } 606 607 /** 608 * 【TAG】非選択状態の場合にforwardを許可するかどうか[true/false]を指定します(初期値:true)。 609 * 610 * @og.tag 611 * 初期値はtrueが設定されています 612 * falseにすると許可されます 613 * 614 * @og.rev 4.0.0.0 (2007/11/09) 新規作成 615 * 616 * @param flag 非選択状態のforward許可 [true:不許可/false:許可] 617 */ 618 public void setUseRedirectCheck(final String flag) { 619 isRedirectCheck = nval( getRequestParameter( flag ),isRedirectCheck ); 620 } 621 622 /** 623 * 【TAG】redirectの処理時に、hiddenパラメータを転送するかどうか[true:する/false:しない]を指定します(初期値:false)。 624 * 625 * @og.tag 626 * submitTag で、gamenId を指定すると、redirect されます。 627 * その場合、従来の画面では、hidden 属性が転送されていなかったため、 628 * 個別に keys,vals で指定する必要がありました。 629 * hidden で記述した値は、redirect でも転送できるようにします。 630 * なお、個別定義済みのパラメータがあり、hiddenパラメータを同じキーの場合は、 631 * 個別パラメータを優先し、hiddenパラメータは転送しません。 632 * 633 * 本来は、gamenId指定の submit の場合でも、必要最小限の値のみ転送すべきで、 634 * この値を true にするのは、過去のJSPソースを、修正せずに使いたいケースに限定してください。 635 * 互換性の関係で、初期値は、false にします。 636 * 637 * @og.rev 6.2.4.0 (2015/05/15) 新規作成 638 * 639 * @param flag 非選択状態のforward許可 [true:不許可/false:許可] 640 */ 641 public void setUseRedirectHidden(final String flag) { 642 isRedirectHidden = nval( getRequestParameter( flag ),isRedirectHidden ); 643 } 644 645 /** 646 * 【TAG】エラーメッセージにSLABELを利用するかどうか[true/false]を指定します(初期値:false)。 647 * 648 * @og.tag 649 * 通常のエラーメッセージは、ラベル(長)が使われますが、これをラベル(短)を使いたい場合に、true にセットします。 650 * ここでのラベル(短)は、タグ修飾なしの、ラベル(短)です。 651 * 標準はfalse:利用しない=ラベル(長)です。 652 * true/false以外を指定した場合はfalse扱いとします。 653 * 654 * ラベルリソースの概要説明があれば表示しますが、useSLabel="true" 時は、概要説明を表示しません。 655 * 656 * @og.rev 7.0.7.0 (2019/12/13) 新規追加 657 * 658 * @param prm SLABEL利用 [true:利用する/false:利用しない] 659 */ 660 public void setUseSLabel( final String prm ) { 661 useSLabel = nval( getRequestParameter( prm ),useSLabel ); 662 } 663 664 /** 665 * このオブジェクトの文字列表現を返します。 666 * 基本的にデバッグ目的に使用します。 667 * 668 * @return このクラスの文字列表現 669 * @og.rtnNotNull 670 */ 671 @Override 672 public String toString() { 673 return ToString.title( this.getClass().getName() ) 674 .println( "VERSION" ,VERSION ) 675 .println( "rowCount" ,rowCount ) 676 .println( "rowNo" ,rowNo ) 677 .println( "dbkeys" ,dbkeys ) 678 .println( "tableIdTemp" ,tableIdTemp ) 679 .println( "dbkeysTemp" ,dbkeysTemp ) 680 .println( "useRedirectCheck" ,isRedirectCheck ) // 6.2.4.0 (2015/05/15) 681 .println( "useRedirectHidden" ,isRedirectHidden ) // 6.2.4.0 (2015/05/15) 682 .println( "Other..." ,getAttributes().getAttribute() ) 683 .fixForm().toString() ; 684 } 685}