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 static org.opengion.fukurou.util.StringUtil.nval ;
021
022import javax.servlet.http.HttpServletResponse ;
023import java.io.IOException;
024
025/**
026 * レスポンスヘッダー情報をセットするタグです。
027 *
028 * レスポンスヘッダーには、キャッシュコントロールやリフレッシュ(ページ自動転送)などを行う
029 * ヘッダー情報をセットすることで、HTML の振る舞いを制御することができます。
030 *
031 * @og.formSample
032 * ●形式:<og:responseHeader cacheKey="[・・・]" />
033 * ●body:なし
034 *
035 * ●Tag定義:
036 *   <og:responseHeader
037 *       cacheControl       【TAG】レスポンスヘッダ に、Cache-Control の値を設定します(初期値:"max-age=0")
038 *       contentType        【TAG】レスポンスヘッダ に、content-Type の値を設定します
039 *       refresh            【TAG】レスポンスヘッダ に、refresh の値を設定します
040 *       refreshURL         【TAG】レスポンスヘッダ に、refresh の値を設定するときに、指定のURLをロードします
041 *       redirect           【TAG】指定されたURLへ一時的なリダイレクトレスポンスを送信します
042 *       status             【TAG】ステータスコードを設定します
043 *       location           【TAG】レスポンスヘッダ に、location の値を設定します
044 *       debug              【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false)
045 *   />
046 *
047 * ●使用例
048 *
049 * @og.rev 3.1.3.0 (2003/04/10) ResponseHeaderTag を 新規作成しました。
050 * @og.group 画面制御
051 *
052 * @version  4.0
053 * @author   Kazuhiko Hasegawa
054 * @since    JDK5.0,
055 */
056public class ResponseHeaderTag extends CommonTagSupport {
057        //* このプログラムのVERSION文字列を設定します。   {@value} */
058        private static final String VERSION = "4.0.0.0 (2005/08/31)" ;
059
060        private static final long serialVersionUID = 400020050831L ;
061
062        private String   pragma                 = null;
063        private String   cacheControl   = "max-age=0";
064        private String   contentType    = null;
065        private int      refresh                = -1;
066        private String   refreshURL             = null;
067        private String   redirect               = null;
068        private int      status                 = -1;
069        private String   location               = null;
070
071        /**
072         * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。
073         *
074         * @og.rev 3.1.9.0 (2003/05/16) refresh 属性を設定した場合は、ページの残りを処理しないように変更。
075         *
076         * @return      後続処理の指示
077         */
078        @Override
079        public int doEndTag() {
080                debugPrint();           // 4.0.0 (2005/02/28)
081                int rtn = EVAL_PAGE;            // ページの残りを評価する。
082
083                HttpServletResponse response = (HttpServletResponse)pageContext.getResponse();
084
085                if( pragma != null ) {
086                        response.setHeader( "Pragma",pragma );
087                }
088
089                if( cacheControl != null ) {
090                        response.setHeader( "Cache-Control",cacheControl );
091                }
092
093                if( contentType != null ) {
094                        response.setContentType( contentType );
095                }
096
097                if( refresh >= 0 ) {
098                        if( refreshURL != null ) {
099                                StringBuilder ref = new StringBuilder();
100                                ref.append( refresh );
101                                ref.append( "; URL=" );
102                                ref.append( response.encodeRedirectURL( refreshURL ) );
103                                response.setHeader( "Refresh",ref.toString() );
104                        }
105                        else {
106                                response.setIntHeader( "Refresh",refresh );
107                        }
108                        rtn = SKIP_PAGE;                // ページの残りの処理を行わない。
109                }
110
111                if( redirect != null ) {
112                        try {
113                                response.sendRedirect( response.encodeRedirectURL( redirect ) );
114                        }
115                        catch( IOException ex ) {
116                                String errMsg = "sendRedirect に失敗しました。" + HybsSystem.CR
117                                                        + " URL=" + redirect + HybsSystem.CR
118                                                        + ex.getMessage();              // 5.1.8.0 (2010/07/01) errMsg 修正
119                                throw new HybsSystemException( errMsg,ex );             // 3.5.5.4 (2004/04/15) 引数の並び順変更
120                        }
121                }
122
123                if( status >= 0 ) {
124                        response.setStatus( status );
125                }
126
127                if( location != null ) {
128                        response.setHeader( "Location",location );
129                }
130
131                return rtn ;
132        }
133
134        /**
135         * タグリブオブジェクトをリリースします。
136         * キャッシュされて再利用されるので、フィールドの初期設定を行います。
137         *
138         */
139        @Override
140        protected void release2() {
141                super.release2();
142                pragma       = null;
143                cacheControl = "max-age=0";
144                contentType  = null;
145                refresh      = -1;
146                refreshURL   = null;
147                redirect     = null;
148                status       = -1;
149                location     = null;
150        }
151
152        /**
153         * 【TAG】レスポンスヘッダ に、Cache-Control の値を設定します(初期値:"max-age=0")。
154         *
155         * @og.tag
156         * このヘッダは、クライアントに対してドキュメントをキャッシュする場合の
157         * 条件を伝えます。初期値は、max-age=0 に設定しています。
158         * 指定する値は、以下のどれかです。
159         *
160         * public        : ドキュメントをキャッシュして良い
161         * private       : ドキュメントが共有されないプライベートの中なら、キャッシュして良い。
162         * no-cache      : ドキュメントをキャッシュしてはいけない。
163         * no-store      : ドキュメントのキャッシュや、ディスク上の一時ファイルも禁止する。
164         * must-revalidate
165         *               : クライアントは、ドキュメントをプロキシではなく、本来の
166         *                 サーバーに確認する必要がある。
167         * proxy-revalidate
168         *               : must-revalidate と同じであるが、共有キャッシュに対してのみ
169         *                 適用される。
170         * max-age=xxx   : ドキュメントが、xxx秒後に陳腐化する。Expires より優先される。
171         * s-max-age=xxx : 共有キャッシュは、ドキュメントが、xxx秒後に陳腐化する。
172         *
173         * @og.rev 3.1.5.1 (2003/04/24) 初期値を、"max-age=0" に変更。
174         * @param       cc Cache-Control
175         */
176        public void setCacheControl( final String cc ) {
177                cacheControl = nval( getRequestParameter( cc ),cacheControl );
178                if( "no-cache".equals( cacheControl ) ) {
179                        pragma = "no-cache";
180                }
181        }
182
183        /**
184         * 【TAG】レスポンスヘッダ に、content-Type の値を設定します。
185         *
186         * @og.tag
187         * このヘッダは、これから返すドキュメントのMIMEタイプを与えます。
188         * MIMEタイプの詳しい規格は、RFC1521 と、RFC1522 です。
189         * <a href="http://www.isi.edu/in-notes/iana/assignments/media-types/media-types" >最新リスト</a>
190         * <a href="http://www.ltsw.se/knbase/internet/mime.htp">未登録タイプ(x-タイプ)</a>
191         *
192         * @param       ct content-Type
193         */
194        public void setContentType( final String ct ) {
195                contentType = nval( getRequestParameter( ct ),contentType );
196        }
197
198        /**
199         * 【TAG】レスポンスヘッダ に、refresh の値を設定します。
200         *
201         * @og.tag
202         * このヘッダは、更新されたページをブラウザが今から何秒後にリクエストすればよいか
203         * ということを伝えます。
204         *
205         * @param       ref 再リクエストさせる秒数
206         */
207        public void setRefresh( final String ref ) {
208                refresh = nval( getRequestParameter( ref ),refresh );
209        }
210
211        /**
212         * 【TAG】レスポンスヘッダ に、refresh の値を設定するときに、指定のURLをロードします。
213         *
214         * @og.tag
215         * このヘッダは、refresh と共に使用され、リクエストする場合のURLを指定します。
216         *
217         * @og.rev 3.1.4.0 (2003/04/18) 属性名変更。(refreshUrl ⇒ refreshURL)
218         *
219         * @param       refurl 再リクエストさせるURL
220         */
221        public void setRefreshURL( final String refurl ) {
222                refreshURL = nval( getRequestParameter( refurl ),refreshURL );
223        }
224
225        /**
226         * 【TAG】指定されたURLへ一時的なリダイレクトレスポンスを送信します。
227         *
228         * @og.tag
229         * 指定されたリダイレクト先のURLを用いて、 クライアントに一時的な
230         * リダイレクトレスポンスを送信します。
231         * URLとしては相対URLを指定することができます。
232         *
233         * @og.rev 3.6.0.0 (2004/09/17) \\\\hn51d4 などのネットワーク名への対応
234         *
235         * @param       rd リダイレクするURL
236         */
237        public void setRedirect( final String rd ) {
238                redirect = nval( getRequestParameter( rd ),redirect );
239                if( redirect != null && redirect.startsWith( "\\\\" ) ) {
240                        redirect = "file://" + redirect;
241                }
242        }
243
244        /**
245         * 【TAG】ステータスコードを設定します。
246         *
247         * @og.tag
248         * ステータスコードを設定します。
249         * 100 ~ 199  100番台はおしらせ的な情報です。
250         * 200 ~ 299  200番台はリクエストが成功したことを表します。
251         * 300 ~ 399  300番台はファイルが移動したことを表します。
252         * 400 ~ 499  400番台はクライアント側のエラーを表します。
253         * 500 ~ 599  500番台はサーバー側のエラーを表します。
254         *
255         * @param       st status ステータスコード
256         */
257        public void setStatus( final String st ) {
258                status = nval( getRequestParameter( st ),status );
259        }
260
261        /**
262         * 【TAG】レスポンスヘッダ に、location の値を設定します。
263         *
264         * @og.tag
265         * このヘッダは、ドキュメントのアドレスを通知します。
266         * 300番台のステータスコードには、このヘッダが必ず付随する必要があります。
267         *
268         * @param       lo ドキュメントのアドレス(ロケーション)
269         */
270        public void setLocation( final String lo ) {
271                location = nval( getRequestParameter( lo ),location );
272        }
273
274        /**
275         * このオブジェクトの文字列表現を返します。
276         * 基本的にデバッグ目的に使用します。
277         *
278         * @return このクラスの文字列表現
279         */
280        @Override
281        public String toString() {
282                return org.opengion.fukurou.util.ToString.title( this.getClass().getName() )
283                                .println( "VERSION"             ,VERSION                )
284                                .println( "pragma"              ,pragma                 )
285                                .println( "cacheControl",cacheControl   )
286                                .println( "contentType" ,contentType    )
287                                .println( "refresh"             ,refresh                )
288                                .println( "refreshURL"  ,refreshURL             )
289                                .println( "redirect"    ,redirect               )
290                                .println( "status"              ,status                 )
291                                .println( "location"    ,location               )
292                                .println( "Other..."    ,getAttributes().getAttribute() )
293                                .fixForm().toString() ;
294        }
295}