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.hayabusa.taglib; 017 018 import org.opengion.hayabusa.common.HybsSystem; 019 import org.opengion.hayabusa.common.HybsSystemException; 020 import org.opengion.fukurou.util.StringUtil; 021 import static org.opengion.fukurou.util.StringUtil.nval ; 022 023 import org.apache.commons.codec.binary.Base64 ; 024 import java.nio.charset.Charset; // 5.5.2.6 (2012/05/25) 025 026 /** 027 * Cookie を読み書きするタグです? 028 * 029 * Cookie は少量の???Servlet から Web ブラウザに送り?ブラウザにそれ? 030 * 維持しもら??以降?アクセスでサーバに送り返してもら??す? 031 * Cookie の値はクライアントを?に識別できるようになって?ので?に 032 * セ?ョン管?用?れて?す? 033 * 034 * Cookie には名前と値が?ありますが、他にコメントやパス、ドメイン? 035 * ?存続期間?バ?ジョンと?たオプショナルな属?もあります? 036 * Web ブラウザの中にはオプショナルな属?の扱?バグがあるものがあります? 037 * こ?ため、Servlet の相互運用性を高めるためにはあまり使わな???でしょ?? 038 * 039 * 標準? JavaScript で登録機?はサポ?トして?したが?メモリのみで、かつ 040 * 画面単位?書き込みのみでした? 041 * 今回の cookie タグでは、永続化(maxAge)の設定や、シス??CONTEXT_NAME以? 042 * での共??ォル???そ?変更、ドメインを指定しての共?domain)などの 043 * 機?を持って?す? 044 * また?漢字コードでの読み書?useBase64)にも対応して?す? 045 * 読み込みに関しては、漢字を?しなければ、{@SYS.COOKIE.カラ?}で、使用可能です? 046 * ?の読み込み、また?漢字コードを含??ーの場合?、読み込み(action="LOAD") 047 * してください。指定?キー以外に、別名に読み込?aliasNames)事も可能です? 048 * 049 * @og.formSample 050 * ●形式? 051 * <og:cookie 052 * action = "SAVE" Cookie に対するアクションを指定します?(SAVE|LOAD|DELETE) 053 * keys = "AAA,BBB" キーをCSV形式で??できます? 054 * vals = "VAL1,VAL2" 値をCSV形式で??できます? 055 * path = "/ge" クライアントがこ? Cookie を返さなくては?な?スを指定します? 056 * domain = ".foo.com" こ? Cookie がどこで生?されたかを表すドメインを指定します? 057 * maxAge = "3600" Cookie の?存続期間を秒単位で設定します? 058 * useBase64 = "false" 漢字等??Byte?を使用する場合に、BASE64で処?ます?[true/false] 059 * > 060 * ●body?な? 061 * 062 * ●Tag定義?? 063 * <og:cookie 064 * action ○?TAG】アクション(SAVE,LOAD,DELETE)をセ?します?(??) 065 * keys ○?TAG】ク?ーのキーをCSV形式で??します?(??) 066 * vals 【TAG】keys属?に対応する?をCSV形式で??しま? 067 * aliasNames 【TAG】ク?ーのキーの別名をCSV形式で??しま? 068 * path 【TAG】クライアントがこ? Cookie を返さなくては?な?スを指定しま?初期値:/+CONTEXT_NAME) 069 * domain 【TAG】この Cookie がどこで生?されたかを表すドメインを指定しま?初期値:付与したサー? 070 * maxAge 【TAG】Cookie の?存続期間を秒単位で設定しま?初期値: -1 ) 071 * useBase64 【TAG】漢字等??を扱??合に、BASE64で処?行うかど?[true/false]を設定しま?初期値:false ) 072 * debug 【TAG】デバッグ??を?力するかど?[true/false]を指定しま?初期値:false) 073 * /> 074 * 075 * ●使用? 076 * 例?設??キーを同時に書き込?とが可能です? 077 * <og:cookie 078 * action="SAVE" keys="CDJ,FG_NAME" vals="{@CDJ},{@NAME}" 079 * /> 080 * 081 * 例?取?cookieタグで取得すると、それ以降では {@CDJ} ?{@NAME} で扱えます? 082 * aliasNames 属?を使わな??合?、keys に?した変数にセ?されます? 083 * <og:cookie 084 * action="LOAD" keys="CDJ,FG_NAME" aliasNames="CDJ,NAME" 085 * /> 086 * 087 * 例?取?SYS パラメータでの取得も可能です? 088 * {@SYS.COOKIE.CDJ} 089 * 090 * 例? QUERY画面では値の表示(LOAD)を行い、RESULT画面で値の設?SAVE)を行うケース 091 * 092 * QUERY画面 093 * <og:cookie action="LOAD" useBase64="true" 094 * keys="CLM,NAME" aliasNames="CLM,LABEL_NAME" /> 095 * 096 * <og:column name="CLM" defaultVal="{@CLM}" /> 097 * <og:column name="LABEL_NAME" defaultVal="{@LABEL_NAME}"/> 098 * 099 * RESULT画面 100 * <og:cookie action="SAVE" maxAge="360000" useBase64="true" 101 * keys="CLM,NAME" vals="{@CLM},{@LABEL_NAME}" /> 102 * 103 * 例? QUERY画面では、{@SYS.COOKIE.カラ?} で取得? 104 * RESULT画面では、ムラタ??シス?共通に使える値をセ?? 105 * 106 * QUERY画面 107 * <og:column name="SYSTEM_ID" defaultVal="{@SYS.COOKIE.SYSTEM_ID}" /> 108 * 109 * RESULT画面 110 * <og:cookie action="SAVE" maxAge="360000" domain=".opengion.org" 111 * keys="SYSTEM_ID" vals="{@SYSTEM_ID}" /> 112 * 113 * @og.rev 3.8.0.2 (2005/06/30) 新規作? 114 * @og.group 画面制御 115 * 116 * @version 0.9.0 2000/10/17 117 * @author Kazuhiko Hasegawa 118 * @since JDK5.0, 119 */ 120 public class CookieTag extends CommonTagSupport { 121 //* こ?プログラ??VERSION??を設定します? {@value} */ 122 private static final String VERSION = "5.5.2.6 (2012/05/25)" ; 123 124 private static final long serialVersionUID = 552620120525L ; 125 126 /** 127 * プラ?フォー?存??ォルト? Charset です? 128 * プラ?フォー?存?を?慮する場合?エンコード指定で作?しておく事をお勧めします? 129 * 130 * @og.rev 5.5.2.6 (2012/05/25) findbugs対? 131 */ 132 private static final Charset DEFAULT_CHARSET = Charset.defaultCharset() ; 133 134 /** action 引数に渡す事?出来?アクション 設?{@value} */ 135 public static final String ACT_SAVE = "SAVE" ; 136 /** action 引数に渡す事?出来?アクション 取?{@value} */ 137 public static final String ACT_LOAD = "LOAD" ; 138 /** action 引数に渡す事?出来?アクション 削除 {@value} */ 139 public static final String ACT_DELETE = "DELETE" ; 140 141 /** action 引数に渡す事?出来?アクション リス? */ 142 private static final String[] ACTION_LIST = new String[] { ACT_SAVE , ACT_LOAD , ACT_DELETE }; 143 144 private String action = null; 145 private String[] keys = null; 146 private String[] vals = null; 147 private String[] aliasNames = null; 148 private String path = "/" + HybsSystem.sys( "CONTEXT_NAME" ); 149 private String domain = null; 150 private int maxAge = -1; 151 private boolean useBase64 = false; 152 153 /** 154 * Taglibの終?グが見つかったときに処??doEndTag() ?オーバ?ライドします? 155 * 156 * @return 後続????(EVAL_PAGE) 157 */ 158 @Override 159 public int doEndTag() { 160 debugPrint(); // 4.0.0 (2005/02/28) 161 actionExec( action ); 162 163 return(EVAL_PAGE); 164 } 165 166 /** 167 * タグリブオブジェクトをリリースします? 168 * キャ?ュされて再利用される?で、フィールド?初期設定を行います? 169 * 170 */ 171 @Override 172 protected void release2() { 173 super.release2(); 174 action = null; 175 keys = null; 176 vals = null; 177 aliasNames = null; 178 path = "/" + HybsSystem.sys( "CONTEXT_NAME" ); 179 domain = null; 180 maxAge = -1; 181 useBase64 = false; 182 } 183 184 /** 185 * アクションを実行します? 186 * 187 * アクションは action 属?で?します? 188 * 189 * @param action アクション(public static final 宣?れて???) 190 */ 191 private void actionExec( final String action ) { 192 193 if( ACT_SAVE.equals( action ) ) { 194 saveCookies( maxAge ); 195 } 196 else if( ACT_LOAD.equals( action ) ) { 197 loadCookies(); 198 } 199 else if( ACT_DELETE.equals( action ) ) { 200 saveCookies( 0 ); // maxAge にゼロをセ?すると削除されます? 201 } 202 else { 203 String errMsg = "??アクションは実行できません。アクションエラー" 204 + HybsSystem.CR 205 + "action=[" + action + "] " 206 + HybsSystem.CR 207 + StringUtil.array2csv( ACTION_LIST ) ; 208 throw new HybsSystemException( errMsg ); 209 } 210 } 211 212 /** 213 * SAVE アクションを実行します? 214 * 215 * ク?ーに書き込みを行います? 216 * 217 * @param maxAge ?存続期? 0 なら削除 ) 218 */ 219 private void saveCookies( final int maxAge ) { 220 // BASE64Encoder encoder = null; 221 for( int i=0; i<keys.length; i++ ) { 222 String value = nval (vals[i],"" ); 223 if( useBase64 && value.length() > 0 ) { 224 // if( encoder == null ) { encoder = new BASE64Encoder(); } 225 // value = encoder.encode( value.getBytes() ) ; 226 227 // byte[] encoded = Base64.encodeBase64( value.getBytes() ); 228 // value = new String( encoded ); 229 byte[] encoded = Base64.encodeBase64( value.getBytes( DEFAULT_CHARSET ) ); // 5.5.2.6 (2012/05/25) findbugs対? 230 value = new String( encoded,DEFAULT_CHARSET ); // 5.5.2.6 (2012/05/25) findbugs対? 231 } 232 setCookie( keys[i], value, maxAge ); 233 } 234 } 235 236 /** 237 * LOAD アクションを実行します? 238 * 239 * ク?ーから読み込みを行います? 240 * 241 */ 242 private void loadCookies() { 243 // BASE64Decoder decoder = null; 244 if( aliasNames == null ) { aliasNames = keys; } 245 246 // try { 247 for( int i=0; i<keys.length; i++ ) { 248 String value = getCookie( keys[i] ); 249 if( useBase64 && value != null && value.length() > 0 ) { 250 // if( decoder == null ) { decoder = new BASE64Decoder(); } 251 // byte[] decoded = decoder.decodeBuffer( value ); 252 // byte[] decoded = Base64.decodeBase64( value.getBytes() ); 253 // value = new String( decoded ); 254 byte[] decoded = Base64.decodeBase64( value.getBytes( DEFAULT_CHARSET ) ); // 5.5.2.6 (2012/05/25) findbugs対? 255 value = new String( decoded,DEFAULT_CHARSET ); // 5.5.2.6 (2012/05/25) findbugs対? 256 } 257 if( value != null ) { 258 setRequestAttribute( aliasNames[i],value ); 259 } 260 } 261 // } 262 // catch( IOException ex ) { 263 // String errMsg = "BASE64Decoder エラー " + ex.toString(); 264 // throw new HybsSystemException( errMsg ); 265 // } 266 } 267 268 /** 269 * 【TAG】アクション(SAVE,LOAD,DELETE)をセ?します? 270 * 271 * @og.tag 272 * アクションは,HTMLから(get/post)?されます?で,ACT_xxx で設定される 273 * フィールド定数値の?れかを??できます? 274 * 無??場合?、なにもしません? 275 * 276 * <table border="1" frame="box" rules="all" > 277 * <th><td>action </td><td>名称</td><td>機?</td></th> 278 * <tr><td>SAVE </td><td>登録</td><td>?? keys のキーに vals の値をセ?します?</td></tr> 279 * <tr><td>LOAD </td><td>取?/td><td>?? keys のク?ー?リクエスト中に)取得します?</td></tr> 280 * <tr><td>DELETE </td><td>削除</td><td>?? keys のク?ーを削除します?</td></tr> 281 * </table> 282 * 283 * @param act アクション(public static final 宣?れて???) 284 * @see <a href="{@docRoot}/constant-values.html#org.opengion.hayabusa.taglib.CookieTag.ACT_DELETE">アクション定数</a> 285 */ 286 public void setAction( final String act ) { 287 action = nval( getRequestParameter( act ),action ); 288 289 if( action != null && !check( action, ACTION_LIST ) ) { 290 String errMsg = "??アクションは実行できません。アクションエラー" 291 + HybsSystem.CR 292 + "action=[" + action + "] " 293 + HybsSystem.CR 294 + StringUtil.array2csv( ACTION_LIST ) ; 295 throw new HybsSystemException( errMsg ); 296 } 297 } 298 299 /** 300 * 【TAG】ク?ーのキーをCSV形式で??します? 301 * 302 * @og.tag 303 * ク?ーにセ?するとき?キーを指定します?カンマ区?で??できます? 304 * vals 属?には、キーに対応する?を?設定してください? 305 * ?方法?、CSV変数を?に?してから、getRequestParameter で値を取得します? 306 * こうしな???タ自身にカンマを持って?場合に?をミスる為です? 307 * 308 * @param key ク?ーのキー 309 */ 310 public void setKeys( final String key ) { 311 keys = getCSVParameter( key ); 312 } 313 314 /** 315 * 【TAG】ク?ーのキーの別名をCSV形式で??します? 316 * 317 * @og.tag 318 * ク?ーから値を取得す?action="LOAD")場合に、読み込みキー(keys)に対応す? 319 * 別名を?することで、別名?変数に読み込んだ値を登録することが?来ます? 320 * 別名を?しな??合?、keys に?された名前が?使用されます? 321 * ?方法?、CSV変数を?に?してから、getRequestParameter で値を取得します? 322 * こうしな???タ自身にカンマを持って?場合に?をミスる為です? 323 * 324 * @param names ク?ーの別? 325 */ 326 public void setAliasNames( final String names ) { 327 aliasNames = getCSVParameter( names ); 328 } 329 330 /** 331 * 【TAG】keys属?に対応する?をCSV形式で??します? 332 * 333 * @og.tag 334 * キーに設定した?を?カンマ区??で?して出来ます? 335 * ??序?、キーと同じにしておいて下さ?? 336 * ?方法?、CSV変数を?に?してから、getRequestParameter で値を取得します? 337 * こうしな???タ自身にカンマを持って?場合に?をミスる為です? 338 * 339 * @param val keys属?に対応する? 340 */ 341 public void setVals( final String val ) { 342 vals = getCSVParameter( val ); 343 } 344 345 /** 346 * 【TAG】クライアントがこ? Cookie を返さなくては?な?スを指定しま?初期値:/+CONTEXT_NAME)? 347 * 348 * @og.tag 349 * こ?値を指定すると Cookie が該当するディレクトリ??さらに? 350 * サブディレクトリに存在する全てのペ?ジから参?できるようになります? 351 * Cookie のパスには Cookie をセ?した Servlet が含まれて?ければなりません? 352 * 例えば?catalog を指定したとします?こ?とき? サーバ? /catalog 以下?全ての 353 * ?レクトリから Cookie が見えるよ?なります? 354 * 初期値は?/" + CONTEXT_NAME です? 355 * 356 * Cookie のパス名指定につ?の詳細は RFC2109 を参照してください? 357 * 358 * @param uri パスを指定するString 359 */ 360 public void setPath( final String uri ) { 361 path = nval( getRequestParameter( uri ),path ); 362 } 363 364 /** 365 * 【TAG】この Cookie がどこで生?されたかを表すドメインを指定しま?初期値:付与したサー?? 366 * 367 * @og.tag 368 * ドメイン名?形式? RFC2109 で?されて?す? 369 * ドメイン名? (.foo.com のように) ドットで始まります? こ?ように設定すると? 370 * Cookie は?された Domain Name System (DNS) のゾーン??サーバから見え? 371 * ようになりま?例えば、www.foo.com) からは見えるけれど、a.b.foo.com からは 372 * 見えな??ようにで???ォルトでは Cookie を付与したサーバにしか送り返しません? 373 * 374 * @param pattern こ? Cookie が見えてもよ?メイン名を?するString 375 */ 376 public void setDomain( final String pattern ) { 377 domain = nval( getRequestParameter( pattern ),domain ); 378 } 379 380 /** 381 * 【TAG】Cookie の?存続期間を秒単位で設定しま?初期値: -1 )? 382 * 383 * @og.tag 384 * 正の値が指定されると Cookie はある秒数が過ぎた後?削除されます? 385 * こ?値は、Cookie の有効期限が?れる ? 存続期間であることに注意してください? 386 * Cookie の現在までの存続期間ではありません? 387 * 388 * ??値は Cookie が永続的に保存されな?とを意味して?す? こ?場合? 389 * Web ブラウザが終?ると Cookie も削除されます? 0 と?値を指定すると 390 * Cookie が削除されることになります? 391 * 初期値は?1(永続的に保存されな?です? 392 * 393 * @param expiry Cookie の?存続期間を秒単位で?する整数値???値は Cookie を保存しな?? 0 な?Cookie を削除する意味となる? 394 */ 395 public void setMaxAge( final String expiry ) { 396 maxAge = nval( getRequestParameter( expiry ),maxAge ); 397 } 398 399 /** 400 * 【TAG】漢字等??を扱??合に、BASE64で処?行うかど?[true/false]を設定しま?初期値:false )? 401 * 402 * @og.tag 403 * ク?ーへの読み書き?、ASCII に限られます?漢字等?コードを書き込??合?? 404 * BASE64でエンコードして書き込??があります?読み込??合も同様です? 405 * ただし??のASCIIは、BASE64 ではエンコードしな?め?外部で?する?があります? 406 * BASE64 で書き込んだ場合?、{@SYS.COOKIE.CDJ} での取得?できませんので? 407 * action="LOAD" で、取得してください? 408 * 初期値は、false(使用しな?です? 409 * 410 * @param flag 漢字等??を扱??合に、BASE64で処?行うかど?[true/false] 411 */ 412 public void setUseBase64( final String flag ) { 413 useBase64 = nval( getRequestParameter( flag ),useBase64 ); 414 } 415 416 /** 417 * こ?オブジェクト???表現を返します? 418 * 基本???目?使用します? 419 * 420 * @return こ?クラスの??表現 421 */ 422 @Override 423 public String toString() { 424 return org.opengion.fukurou.util.ToString.title( this.getClass().getName() ) 425 .println( "VERSION" ,VERSION ) 426 .println( "action" ,action ) 427 .println( "keys" ,keys ) 428 .println( "vals" ,vals ) 429 .println( "aliasNames" ,aliasNames ) 430 .println( "path" ,path ) 431 .println( "domain" ,domain ) 432 .println( "maxAge" ,maxAge ) 433 .println( "useBase64" ,useBase64 ) 434 .println( "Other..." ,getAttributes().getAttribute() ) 435 .fixForm().toString() ; 436 } 437 }