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 }