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