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 * <caption>アクションの説?/caption>
278 * <tr><th>action </th><th>名称</th><th>機?</th></tr>
279 * <tr><td>SAVE </td><td>登録</td><td>?? keys のキーに vals の値をセ?します?</td></tr>
280 * <tr><td>LOAD </td><td>取?/td><td>?? keys のク?ー?リクエスト中に)取得します?</td></tr>
281 * <tr><td>DELETE </td><td>削除</td><td>?? keys のク?ーを削除します?</td></tr>
282 * </table>
283 *
284 * @param act アクション(public static final 宣?れて???)
285 * @see <a href="../../../../constant-values.html#org.opengion.hayabusa.taglib.CookieTag.ACT_DELETE">アクション定数</a>
286 */
287 public void setAction( final String act ) {
288 action = nval( getRequestParameter( act ),action );
289
290 if( action != null && !check( action, ACTION_LIST ) ) {
291 String errMsg = "??アクションは実行できません。アクションエラー"
292 + HybsSystem.CR
293 + "action=[" + action + "] "
294 + HybsSystem.CR
295 + StringUtil.array2csv( ACTION_LIST ) ;
296 throw new HybsSystemException( errMsg );
297 }
298 }
299
300 /**
301 * 【TAG】ク?ーのキーをCSV形式で??します?
302 *
303 * @og.tag
304 * ク?ーにセ?するとき?キーを指定します?カンマ区?で??できます?
305 * vals 属?には、キーに対応する?を?設定してください?
306 * ?方法?、CSV変数を?に?してから、getRequestParameter で値を取得します?
307 * こうしな???タ自身にカンマを持って?場合に?をミスる為です?
308 *
309 * @param key ク?ーのキー
310 */
311 public void setKeys( final String key ) {
312 keys = getCSVParameter( key );
313 }
314
315 /**
316 * 【TAG】ク?ーのキーの別名をCSV形式で??します?
317 *
318 * @og.tag
319 * ク?ーから値を取得す?action="LOAD")場合に、読み込みキー(keys)に対応す?
320 * 別名を?することで、別名?変数に読み込んだ値を登録することが?来ます?
321 * 別名を?しな??合?、keys に?された名前が?使用されます?
322 * ?方法?、CSV変数を?に?してから、getRequestParameter で値を取得します?
323 * こうしな???タ自身にカンマを持って?場合に?をミスる為です?
324 *
325 * @param names ク?ーの別?
326 */
327 public void setAliasNames( final String names ) {
328 aliasNames = getCSVParameter( names );
329 }
330
331 /**
332 * 【TAG】keys属?に対応する?をCSV形式で??します?
333 *
334 * @og.tag
335 * キーに設定した?を?カンマ区??で?して出来ます?
336 * ??序?、キーと同じにしておいて下さ??
337 * ?方法?、CSV変数を?に?してから、getRequestParameter で値を取得します?
338 * こうしな???タ自身にカンマを持って?場合に?をミスる為です?
339 *
340 * @param val keys属?に対応する?
341 */
342 public void setVals( final String val ) {
343 vals = getCSVParameter( val );
344 }
345
346 /**
347 * 【TAG】クライアントがこ? Cookie を返さなくては?な?スを指定しま?初期値:/+CONTEXT_NAME)?
348 *
349 * @og.tag
350 * こ?値を指定すると Cookie が該当するディレクトリ??さらに?
351 * サブディレクトリに存在する全てのペ?ジから参?できるようになります?
352 * Cookie のパスには Cookie をセ?した Servlet が含まれて?ければなりません?
353 * 例えば?catalog を指定したとします?こ?とき? サーバ? /catalog 以下?全ての
354 * ?レクトリから Cookie が見えるよ?なります?
355 * 初期値は?/" + CONTEXT_NAME です?
356 *
357 * Cookie のパス名指定につ?の詳細は RFC2109 を参照してください?
358 *
359 * @param uri パスを指定するString
360 */
361 public void setPath( final String uri ) {
362 path = nval( getRequestParameter( uri ),path );
363 }
364
365 /**
366 * 【TAG】この Cookie がどこで生?されたかを表すドメインを指定しま?初期値:付与したサー??
367 *
368 * @og.tag
369 * ドメイン名?形式? RFC2109 で?されて?す?
370 * ドメイン名? (.foo.com のように) ドットで始まります? こ?ように設定すると?
371 * Cookie は?された Domain Name System (DNS) のゾーン??サーバから見え?
372 * ようになりま?例えば、www.foo.com) からは見えるけれど、a.b.foo.com からは
373 * 見えな??ようにで???ォルトでは Cookie を付与したサーバにしか送り返しません?
374 *
375 * @param pattern こ? Cookie が見えてもよ?メイン名を?するString
376 */
377 public void setDomain( final String pattern ) {
378 domain = nval( getRequestParameter( pattern ),domain );
379 }
380
381 /**
382 * 【TAG】Cookie の?存続期間を秒単位で設定しま?初期値: -1 )?
383 *
384 * @og.tag
385 * 正の値が指定されると Cookie はある秒数が過ぎた後?削除されます?
386 * こ?値は、Cookie の有効期限が?れる ? 存続期間であることに注意してください?
387 * Cookie の現在までの存続期間ではありません?
388 *
389 * ??値は Cookie が永続的に保存されな?とを意味して?す? こ?場合?
390 * Web ブラウザが終?ると Cookie も削除されます? 0 と?値を指定すると
391 * Cookie が削除されることになります?
392 * 初期値は?1(永続的に保存されな?です?
393 *
394 * @param expiry Cookie の?存続期間を秒単位で?する整数値???値は Cookie を保存しな?? 0 な?Cookie を削除する意味となる?
395 */
396 public void setMaxAge( final String expiry ) {
397 maxAge = nval( getRequestParameter( expiry ),maxAge );
398 }
399
400 /**
401 * 【TAG】漢字等??を扱??合に、BASE64で処?行うかど?[true/false]を設定しま?初期値:false )?
402 *
403 * @og.tag
404 * ク?ーへの読み書き?、ASCII に限られます?漢字等?コードを書き込??合??
405 * BASE64でエンコードして書き込??があります?読み込??合も同様です?
406 * ただし??のASCIIは、BASE64 ではエンコードしな?め?外部で?する?があります?
407 * BASE64 で書き込んだ場合?、{@SYS.COOKIE.CDJ} での取得?できませんので?
408 * action="LOAD" で、取得してください?
409 * 初期値は、false(使用しな?です?
410 *
411 * @param flag 漢字等??を扱??合に、BASE64で処?行うかど?[true/false]
412 */
413 public void setUseBase64( final String flag ) {
414 useBase64 = nval( getRequestParameter( flag ),useBase64 );
415 }
416
417 /**
418 * こ?オブジェクト???表現を返します?
419 * 基本???目?使用します?
420 *
421 * @return こ?クラスの??表現
422 */
423 @Override
424 public String toString() {
425 return org.opengion.fukurou.util.ToString.title( this.getClass().getName() )
426 .println( "VERSION" ,VERSION )
427 .println( "action" ,action )
428 .println( "keys" ,keys )
429 .println( "vals" ,vals )
430 .println( "aliasNames" ,aliasNames )
431 .println( "path" ,path )
432 .println( "domain" ,domain )
433 .println( "maxAge" ,maxAge )
434 .println( "useBase64" ,useBase64 )
435 .println( "Other..." ,getAttributes().getAttribute() )
436 .fixForm().toString() ;
437 }
438 }