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; 020 021import org.opengion.hayabusa.resource.GUIInfo; 022import org.opengion.hayabusa.resource.UserInfo; 023import org.opengion.hayabusa.resource.FavoriteGUIData; 024 025import org.opengion.fukurou.util.XHTMLTag; 026 027import static org.opengion.fukurou.util.StringUtil.nval ; 028 029import javax.servlet.http.HttpServletRequest ; 030import javax.servlet.http.HttpServletResponse; 031 032import java.util.Enumeration; 033import java.util.ArrayList; 034import java.util.Map; 035import java.util.HashMap; 036 037import java.io.IOException; 038 039/** 040 * お気に入りリンクを作成するタグです(通常はresult.jspに組込み)。 041 * 042 * 画面検索時の引数やユーザー情報を元にして、ダイレクトに再検索できる 043 * リンクを作成します。このリンクをお気に入り等にセーブしておき、次回検索時にも 044 * 使用できるようにします。 045 * 046 * @og.formSample 047 * ●形式:<og:favoriteLink direct="true" target="_blank" method="GET" /> 048 * ●body:あり(EVAL_BODY_BUFFERED:BODYを評価し、{@XXXX} を解析します) 049 * 050 * ●Tag定義: 051 * <og:favoriteLink 052 * target 【TAG】リンク先の文書を表示させるフレーム、またはウィンドウの名前を指定します(初期値:_blank) 053 * direct 【TAG】直接アクセスできる形式のリンクを作成するかどうか[true/false]を指定します(初期値:false) 054 * method 【TAG】リンクの作成元となるメソッド[POST/GET/ALL]を指定します(初期値:GET) 055 * href 【TAG】リンクを作成する時の転送先アドレスを指定します(初期値:index.jsp) 056 * lbl 【TAG】ラベルリソースのラベルIDを指定します 057 * linkCache 【TAG】リンクをキャッシュするかどうか[true/false]を指定します(初期値:false) 058 * lastQueryRedirect 【TAG】キャッシュされたリンク先に転送するかどうか[true/false]を指定します(初期値:false) 059 * debug 【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false) 060 * useIcon 【TAG】お気に入りアイコンリンクを作成するかどうか[true/false]を指定します(初期値:false) 061 * > ... Body ... 062 * </og:favoriteLink> 063 * 064 * ●使用例: 065 * 直接お気に入りのリンクを作成する。 066 * デフォルト属性を使用(direct="true" target="_blank" method="GET") 067 * <og:favoriteLink > Favorite Link </og:favoriteLink > 068 * 069 * @og.group 画面部品 070 * 071 * @version 4.0 072 * @author Kazuhiko Hasegawa 073 * @since JDK5.0, 074 */ 075public class FavoriteLinkTag extends CommonTagSupport { 076 //* このプログラムのVERSION文字列を設定します。 {@value} */ 077 private static final String VERSION = "5.0.0.2 (2009/09/15)" ; 078 079 private static final long serialVersionUID = 500220090915L ; 080 081 private static final Map<String,String> lastQuery = new HashMap<String,String>(); // 3.5.6.2 (2004/07/05) 082 083 private boolean direct = false; // 3.0.0.0 初期値変更 084 private String target = "_blank"; // 3.6.0.7 (2004/11/06) 085 private String method = "GET"; 086 private String href = "index.jsp"; // 3.8.8.2 (2007/01/26) 087 private boolean linkCache = false; // 3.5.5.9 (2004/06/07) 088 private boolean redirect = false; // 3.5.5.9 (2004/06/07) 089 private boolean useIcon = false; // 4.1.1.0 (2008/02/13) 090 091 /** 092 * Taglibの開始タグが見つかったときに処理する doStartTag() を オーバーライドします。 093 * 094 * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。ボディが存在する場合のみボディが呼ばれる対応。 095 * @og.rev 3.5.5.9 (2004/06/07) リンクキャッシュより最終画面を転送表示します。 096 * @og.rev 5.0.0.2 (2009/09/15) xss対応⇒チェックする 097 * 098 * @return 後続処理の指示 099 */ 100 @Override 101 public int doStartTag() { 102 // 5.0.0.2 (2009/09/15) 強制False 103 // useXssCheck( false ); 104 105 // 3.5.5.9 (2004/06/07) リンクキャッシュより最終画面を転送表示 106 if( redirect ) { 107 final String page ; 108 synchronized( lastQuery ) { 109 page = lastQuery.get( getUserInfo( "ID" ) ) ; 110 } 111 if( page != null ) { 112 HttpServletResponse response = (HttpServletResponse)pageContext.getResponse(); 113 String url = response.encodeRedirectURL( page ); 114 try { 115 response.sendRedirect( url ); 116 } 117 catch ( IOException ex ) { 118 String errMsg = "最終画面の転送時のリダイレクトエラー" + toString(); 119 throw new HybsSystemException( errMsg,ex ); 120 } 121 122 return( SKIP_BODY ); 123 } 124 } 125 126 set( "body",getMsglbl() ); 127 return( EVAL_BODY_BUFFERED ); // Body を評価する。( extends BodyTagSupport 時) 128 } 129 130 /** 131 * Taglibのタグ本体を処理する doAfterBody() を オーバーライドします。 132 * 133 * @og.rev 3.1.1.0 (2003/03/28) ボディの内容を取得する処理を、CommonTagSupport で行う。 134 * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。ボディが存在する場合のみボディが呼ばれる対応。 135 * 136 * @return 後続処理の指示(SKIP_BODY) 137 */ 138 @Override 139 public int doAfterBody() { 140 141 String label = getBodyString(); 142 143 if( label != null && label.length() > 0 ) { 144 set( "body",label ); 145 } 146 147 return(SKIP_BODY); 148 } 149 150 /** 151 * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。 152 * 153 * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。release2() を doEndTag()で呼ぶ。 154 * @og.rev 4.1.1.0 (2008/0213) お気に入りアイコンリンクの作成 155 * 156 * @return 後続処理の指示 157 */ 158 @Override 159 public int doEndTag() { 160 debugPrint(); // 4.0.0 (2005/02/28) 161 162 // method による条件判断。 163 String requestMethod = ((HttpServletRequest)getRequest()).getMethod(); 164 if( method != null && 165 ( "ALL".equalsIgnoreCase( method ) || 166 method.equalsIgnoreCase( requestMethod ) ) ) { 167 // 4.1.1.0 (2008/0213) お気に入りアイコンリンクの作成 168 if ( useIcon ) { 169 jspPrint( getFavoriteIcon() ); 170 } 171 else { 172 jspPrint( makeTag() ); 173 } 174 } 175 176 return(EVAL_PAGE); 177 } 178 179 /** 180 * タグリブオブジェクトをリリースします。 181 * キャッシュされて再利用されるので、フィールドの初期設定を行います。 182 * 183 * @og.rev 2.0.0.4 (2002/09/27) カスタムタグの release() メソッドを、追加 184 * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。release2() を doEndTag()で呼ぶ。 185 * @og.rev 3.5.5.9 (2004/06/07) linkCache , redirect 属性を追加 186 * @og.rev 3.6.0.7 (2004/11/06) target 属性の初期値を _new から _blank に変更 187 * @og.rev 3.8.8.2 (2007/01/26) href 属性を追加 188 * 189 */ 190 @Override 191 protected void release2() { 192 super.release2(); 193 direct = false; 194 target = "_blank"; // 3.6.0.7 (2004/11/06) 195 method = "GET"; 196 href = "index.jsp"; // 3.8.8.2 (2007/01/26) 197 linkCache = false; // 3.5.5.9 (2004/06/07) 198 redirect = false; // 3.5.5.9 (2004/06/07) 199 } 200 201 /** 202 * お気に入りリンクを作成します。 203 * 204 * @og.rev 3.8.8.2 (2007/01/26) href 属性を追加 205 * 206 * @return お気に入りリンクタグ文字列 207 */ 208 protected String makeTag() { 209 HttpServletRequest request = (HttpServletRequest)getRequest(); 210 211 // ダイレクトリンク時の設定 212 213 // リンクの作成 214 // http://C00000:C00000@hn50g5:8080/dbdef/jsp/index.jsp?GAMENID=xxx&command=NEW&key=val 215 StringBuilder link = new StringBuilder( HybsSystem.BUFFER_MIDDLE ); 216 217 link.append( "http://" ); 218 link.append( request.getServerName() ).append( ":" ); // hn50g5: 219 link.append( request.getServerPort() ); // 8823 220 link.append( request.getContextPath() ); // /dbdef 221 link.append( "/jsp/" ); 222 223 // 4.0.0 (2005/01/31) 224 String direct_jsp = getGUIInfoAttri( "ADDRESS" ) + "/" + (String)getSessionAttribute( "JSPID" ); 225 226 String hrefUrl = link.toString() ; 227 if( direct ) { 228 set( "href" , hrefUrl + direct_jsp ); 229 } 230 else { 231 set( "href" , hrefUrl + href ); // 3.8.8.2 (2007/01/26) 232 } 233 234 set( "target" ,target ); 235 set( "title" ,getGUIInfoAttri( "LABEL" ) ); // 4.0.0 (2005/01/31) 236 237 String urlEnc = makeUrlEncode( request ); 238 239 // linkCache による、最終リクエストのアドレスを格納しておきます。 240 if( linkCache ) { 241 String key = getUserInfo( "ID" ); 242 String val = hrefUrl + direct_jsp + "?" + urlEnc ; 243 synchronized( lastQuery ) { 244 lastQuery.put( key,val ); 245 } 246 } 247 248 return XHTMLTag.link( getAttributes(),urlEnc ) ; 249 } 250 251 /** 252 * URLエンコードを行ったリンク情報を作成します。 253 * 254 * @og.rev 3.1.0.0 (2003/03/20) Vector を使用している箇所で、非同期でも構わない箇所を、ArrayList に置換え。 255 * @og.rev 3.1.2.0 (2003/04/07) 画面IDと実画面ディレクトリとの関連見直し(DIRの代りにGAMENIDを渡すように変更) 256 * @og.rev 3.1.8.0 (2003/05/16) 内部で作成している GAMENID 属性をセットしないように変更。 257 * @og.rev 4.0.0.0 (2007/07/11) submitTag で作成されたボタンパラメータは、次ページへ転送しません。 258 * @og.rev 5.0.0.2 (2009/09/15) xssチェック対応 259 * 260 * @param request HttpServletRequestオブジェクト 261 * 262 * @return URLエンコードを行ったリンク情報 263 */ 264 private String makeUrlEncode( final HttpServletRequest request ) { 265 Enumeration<?> enume = request.getParameterNames(); // 4.3.3.6 (2008/11/15) Generics警告対応 266 ArrayList<String> v_keys = new ArrayList<String>(); 267 ArrayList<String> v_vals = new ArrayList<String>(); 268 while( enume.hasMoreElements() ) { 269 String key = String.valueOf( enume.nextElement() ); 270 if( key != null && key.startsWith( HybsSystem.NO_XFER_KEY ) ) { 271 continue; 272 } 273 274 // String val = getRequestValue( key ); 275 String val = getRequestValue( key, false ); // 5.0.0.2 (2009/09/15) 276 if( val != null && val.length() > 0 ) { 277 v_keys.add( key ); 278 v_vals.add( val ); 279 } 280 } 281 282 String[] keys = v_keys.toArray( new String[v_keys.size()] ); 283 String[] vals = v_vals.toArray( new String[v_vals.size()] ); 284 285 return XHTMLTag.urlEncode( keys,vals ); 286 } 287 288 /** 289 * お気に入りアイコンを取得します。 290 * @og.rev 4.1.1.0 (2008/02/12) 新規追加 291 * 292 * @return お気に入りアイコンのリンクを返します。 293 */ 294 private String getFavoriteIcon() { 295 GUIInfo guiInfo = ( GUIInfo )getSessionAttribute( HybsSystem.GUIINFO_KEY ); 296 String mscVal = getRequestValue( "MSC" ); 297 StringBuilder buf = new StringBuilder( HybsSystem.BUFFER_SMALL ); 298 299 if( ( guiInfo.isRead() ) && ( mscVal.length() != 0 ) ) { 300 String gamenId = guiInfo.getKey(); 301 UserInfo userInfo = getUser(); 302 Map<String,FavoriteGUIData> favoriteMap = userInfo.getFavoriteMap(); 303 304 String fgEdit,image,updateLabel; 305 if( favoriteMap.containsKey( gamenId ) ){ 306 fgEdit = "0"; 307 image = "FAV_MENU_OUT.gif"; 308 updateLabel = getLabel( "DELETE" ); 309 } 310 else { 311 fgEdit = "1"; 312 image = "FAV_MENU_IN.gif"; 313 updateLabel = getLabel( "INSERT" ); 314 } 315 316 String geContextName = HybsSystem.sys( "GE_CONTEXT_NAME" ); 317 if ( geContextName.length() == 0 ) { 318 String errMsg = "システムパラメータ GE_CONTEXT_NAME が設定されていません。"; 319 throw new HybsSystemException( errMsg ); 320 } 321 322 buf.append( "<a href=\"/").append( geContextName ); 323 buf.append("/jsp/GE0014/update.jsp?fgEdit=" ).append( fgEdit ); 324 buf.append( "&command=NEW" ); 325 buf.append( "&SYSTEM_ID=" ).append( userInfo.getParameter( "SYSTEM_ID" ) ); 326 buf.append( "&GUIKEY=" ).append( gamenId ); 327 buf.append( "&CONTEXT_URL=" ).append( userInfo.getParameter( "CONTEXT_URL" ) ); 328 buf.append( "\">"); 329 buf.append("<img src=\"" ).append( userInfo.getParameter( "JSP" ) ); 330 buf.append( "/image/" ).append( image ).append( "\" " ); 331 buf.append( "title=" ).append( "\"" ).append( getLabel( "FAVORITE_MENU" ) ); 332 buf.append( " " ).append( updateLabel ).append( "\"" ); 333 buf.append( "/></a>" ); 334 } 335 336 return buf.toString(); 337 } 338 339 /** 340 * 【TAG】直接アクセスできる形式のリンクを作成するかどうか[true/false]を指定します(初期値:false)。 341 * 342 * @og.tag 343 * trueは、指定の画面のフレームレベルでの指定になります。false は、トップフレームを 344 * 含む形なので、通常の登録画面と同じ形式になります。 345 * 初期値は、false(直接リンクしない)です。 346 * 347 * @param flag ダイレクトリンクの作成可否 348 */ 349 public void setDirect( final String flag ) { 350 direct = nval( getRequestParameter( flag ),direct ); 351 } 352 353 /** 354 * 【TAG】リンク先の文書を表示させるフレーム、またはウィンドウの名前を指定します(初期値:_blank)。 355 * 356 * @og.tag リンク先のフレーム名(ターゲット属性)を設定します。 357 * 358 * @param flag リンク先の文書のフレーム名(ターゲット属性) 359 */ 360 public void setTarget( final String flag ) { 361 target = nval( getRequestParameter( flag ),target ); 362 } 363 364 /** 365 * 【TAG】リンクを作成する時の転送先アドレスを指定します(初期値:index.jsp)。 366 * 367 * @og.tag 368 * direct="false"(初期値)に使用されるリンクの転送先アドレスを指定します。 369 * 初期値は、index.jspです。 370 * 371 * @param url 転送先アドレス 372 */ 373 public void setHref( final String url ) { 374 href = nval( getRequestParameter( url ),href ); 375 } 376 377 /** 378 * 【TAG】リンクの作成元となるメソッド[POST/GET/ALL]を指定します(初期値:GET)。 379 * 380 * @og.tag 381 * ここで指定したメソッドでリクエストされた場合のみ、リンクを作成します。 382 * 初期値は、GET です。(つまり GET のみリンクを作成します。) 383 * これは、POST では、引数が付かない為です。(実際は付ける事ができますが・・・) 384 * ALL は、どちらの場合でもリンクを作成しますが、先に述べたように POST では 385 * 引数がつきません。 386 * 初期値は、GETです。 387 * 388 * @param flag リンクの作成元となるメソッド [POST/GET/ALL] 389 */ 390 public void setMethod( final String flag ) { 391 method = nval( getRequestParameter( flag ),method ); 392 } 393 394 /** 395 * 【TAG】リンクをキャッシュするかどうか[true/false]を指定します(初期値:false)。 396 * 397 * @og.tag 398 * この、favoriteLink で指定された画面を、ユーザー毎にキャッシュします。 399 * キャッシュされた画面は、lastQuery を指定することで、取り出し(転送) 400 * することが出来ます。 401 * ここでのキャッシュは、direct="true" を指定した場合のアドレスです。 402 * direct="false" は、index.jsp からのフレーム形式の為、メール等で 403 * 送り、後ほど再開するような使い方(または、ワークフロー的な使い方) 404 * を想定していますが、direct="true" により単独フレームデータを、 405 * リアルタイムで使用するケース(EXCELのWebクエリーなど)で使用します。 406 * 初期値は、falseです。 407 * 408 * @og.rev 3.5.5.9 (2004/06/07) リンクキャッシュより最終画面を転送表示します。 409 * 410 * @param flag リンクをキャッシュするかどうか [true:する/false:しない] 411 */ 412 public void setLinkCache( final String flag ) { 413 linkCache = nval( getRequestParameter( flag ),linkCache ); 414 } 415 416 /** 417 * 【TAG】キャッシュされたリンク先に転送するかどうか[true/false]を指定します(初期値:false)。 418 * 419 * @og.tag 420 * この、favoriteLink で指定された画面を、キャッシュします。 421 * キャッシュされた画面は、lastQuery を指定することで、取り出し(転送) 422 * することが出来ます。 423 * ここでのキャッシュは、direct="true" を指定した場合のアドレスです。 424 * direct="false" は、index.jsp からのフレーム形式の為、メール等で 425 * 送り、後ほど再開するような使い方(または、ワークフロー的な使い方) 426 * を想定していますが、direct="true" により単独フレームデータを、 427 * リアルタイムで使用するケース(EXCELのWebクエリーなど)で使用します。 428 * 初期値は、falseです。 429 * 430 * @og.rev 3.5.5.9 (2004/06/07) リンクキャッシュより最終画面を転送表示します。 431 * 432 * @param flag リンクをキャッシュするかどうか [true:する/false:しない] 433 */ 434 public void setLastQueryRedirect( final String flag ) { 435 redirect = nval( getRequestParameter( flag ),redirect ); 436 } 437 438 /** 439 * 【TAG】お気に入りアイコンリンクを作成するかどうか[true/false]を指定します(初期値:false)。 440 * 441 * @og.tag 442 * 初期値は、falseです。 443 * 444 * @og.rev 4.1.1.0 (2008/02/13) 新規追加。 445 * 446 * @param flag お気に入りアイコンリンクを作成するかどうか [true:する/false:しない] 447 */ 448 public void setUseIcon( final String flag ) { 449 useIcon = nval( getRequestParameter( flag ),useIcon ); 450 } 451 452 /** 453 * リンクキャッシュをクリアします。 454 * この時、poolされているオブジェクトは、ResourceManager#clear() メソッドを 455 * 呼び出します。 456 * 457 * @og.rev 3.5.5.9 (2004/06/07) 新規作成 458 */ 459 public static void clear() { 460 synchronized( lastQuery ) { 461 lastQuery.clear(); 462 } 463 } 464 465 /** 466 * このオブジェクトの文字列表現を返します。 467 * 基本的にデバッグ目的に使用します。 468 * 469 * @return このクラスの文字列表現 470 */ 471 @Override 472 public String toString() { 473 return org.opengion.fukurou.util.ToString.title( this.getClass().getName() ) 474 .println( "VERSION" ,VERSION ) 475 .println( "direct" ,direct ) 476 .println( "target" ,target ) 477 .println( "method" ,method ) 478 .println( "linkCache" ,linkCache ) 479 .println( "redirect" ,redirect ) 480 .println( "Other..." ,getAttributes().getAttribute() ) 481 .fixForm().toString() ; 482 } 483}