    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 static org.opengion.fukurou.util.StringUtil.nval;
    019
    020import org.opengion.hayabusa.common.HybsSystem;
    021import org.opengion.hayabusa.common.HybsSystemException;
    022import org.opengion.fukurou.util.LogWriter;
    023import org.opengion.fukurou.util.FileString;
    024
    025import javax.servlet.ServletRequest ;
    026import javax.servlet.http.HttpServletRequest ;
    027
    028/**
    029 * BODY部に記述されたエンジン固有の文字列({&#064;XXXX}など)を、
    030 *  ユーザー情報のエンコーディングに変換するタグです。
    031 *
    032 * XML形式で 日本語コードのパースが、JSPエンジン(Tomcat)でサポート
    033 * されるまでの、暫定的なタグです。
    034 * なお、このタグの内部に存在するカスタムタグは、先に実行されるため
    035 * 漢字コードは、変換されません。
    036 *
    037 * @og.formSample
    038 * ●形式：&lt;og:text &gt;･･･&lt;/og:text&gt;
    039 * ●body：あり(EVAL_BODY_BUFFERED:BODYを評価し、{&#064;XXXX} を解析します)
    040 *
    041 * ●Tag定義：
    042 *   &lt;og:text
    043 *       value              【TAG】value 値に直接書かれた漢字コードをShift_JIS に変換します
    044 *       include            【TAG】動的にファイルを include します
    045 *       xssCheck           【TAG】リクエスト情報の HTMLTag開始/終了文字(&gt;&lt;) 存在チェックを実施するかどうか[true/false]を設定します (初期値:USE_XSS_CHECK[=true])
    046 *       debug              【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false)
    047 *   &gt;   ... Body ...
    048 *   &lt;/og:text&gt;
    049 *
    050 * ●使用例
    051 *      ・&lt;og:text &gt;
    052 *            &lt;p&gt;あいおえお：&lt;input name="PN" value="{&#064;PN}" /&gt; &lt;/p&gt;
    053 *        &lt;/og:text&gt;
    054 *      ・&lt;og:text value="あいうえお" /&gt;
    055 *
    056 *     動的にファイルを include することが出来ます。
    057 *      ・&lt;og:text include="{&#064;query}.txt" /&gt;
    058 *
    059 * @og.group 画面部品
    060 *
    061 * @version  4.0
    062 * @author   Kazuhiko Hasegawa
    063 * @since    JDK5.0,
    064 */
    065public class TextTag extends CommonTagSupport {
    066        //* このプログラムのVERSION文字列を設定します。   {@value} */
    067        private static final String VERSION = "4.0.0.0 (2007/11/30)" ;
    068
    069        private static final long serialVersionUID = 400020071130L ;
    070
    071        private String  value   = null;
    072        private boolean useInclude = false;
    073
    074        private boolean xssCheck        = HybsSystem.sysBool( "USE_XSS_CHECK" ); // 5.9.10.5 (2010/06/01) XSS対策
    075
    076        /**
    077         * Taglibの開始タグが見つかったときに処理する doStartTag() を オーバーライドします。
    078         *
    079         * @og.rev 5.9.10.5 (2016/07/22) xssCheck
    080         *
    081         * @return      後続処理の指示( EVAL_BODY_BUFFERED )
    082         */
    083        @Override
    084        public int doStartTag() {
    085                useXssCheck( xssCheck ); // 5.9.10.5 (2016/07/22)
    086                return( EVAL_BODY_BUFFERED );   // Body を評価する。( extends BodyTagSupport 時)
    087        }
    088
    089        /**
    090         * Taglibのタグ本体を処理する doAfterBody() を オーバーライドします。
    091         *
    092         * @og.rev 2.2.0.0 (2002/12/17) 中国語(国際化)対応 エンコードの取得方法変更
    093         * @og.rev 3.0.0.0 (2002/12/25) StringUtil#changeString 廃止
    094         * @og.rev 3.1.1.0 (2003/03/28) ボディの内容を取得する処理を、CommonTagSupport で行う。
    095         * @og.rev 4.0.0.0 (2007/10/12) 処理中にエラーを発生させないようにしする。
    096         *
    097         * @return      後続処理の指示(SKIP_BODY)
    098         */
    099        @Override
    100        public int doAfterBody() {
    101                if( !useInclude && value == null ) {
    102                        // 4.0.0.0 (2007/10/12) 処理中にエラーを発生させない
    103                        try {
    104                                value = getBodyString();
    105                        }
    106                        catch( HybsSystemException ex ) {       // 主に、UserInfo が見つからない場合
    107                                value = getBodyContent().getString() ;
    108                        }
    109
    110                        if( value != null && value.indexOf( "<og:" ) >= 0 ) {
    111                                String errMsg = "このタグの BODY部に opengion タグが記述されています。"
    112                                                        + "BODY部ではopengion タグは使用できません。";
    113                                throw new HybsSystemException( errMsg );
    114                        }
    115                }
    116
    117                return(SKIP_BODY);
    118        }
    119
    120        /**
    121         * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。
    122         *
    123         * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。release2() を doEndTag()で呼ぶ。
    124         *
    125         * @return      後続処理の指示
    126         */
    127        @Override
    128        public int doEndTag() {
    129                debugPrint();           // 4.0.0 (2005/02/28)
    130                jspPrint( value );
    131
    132                return(EVAL_PAGE);
    133        }
    134
    135        /**
    136         * タグリブオブジェクトをリリースします。
    137         * キャッシュされて再利用されるので、フィールドの初期設定を行います。
    138         *
    139         * @og.rev 2.0.0.4 (2002/09/27) カスタムタグの release() メソッドを、追加
    140         * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。release2() を doEndTag()で呼ぶ。
    141         * @og.rev 5.9.10.5 (2016/07/22) xssCheck
    142         *
    143         */
    144        @Override
    145        protected void release2() {
    146                super.release2();
    147                value           = null;
    148                useInclude      = false;
    149                xssCheck        = HybsSystem.sysBool( "USE_XSS_CHECK" );        // 5.9.10.5 (2016/07/22)
    150        }
    151
    152        /**
    153         * 【TAG】value 値に設定します。
    154         *
    155         * @og.tag
    156         * ここで、value に設定した場合は、BODY 部は無視されます。
    157         * なお、このタグでは、エラー発生時でも継続して処理を続けられるようにします。
    158         * error.jsp などのエラー処理画面で、このタグを使用するケースがある為です。
    159         *
    160         *  &lt;og:text value="あいうえお" /&gt;
    161         *
    162         * @og.rev 2.2.0.0 (2002/12/17) 中国語(国際化)対応 エンコードの取得方法変更
    163         * @og.rev 3.0.0.0 (2002/12/25) StringUtil#changeString 廃止
    164         * @og.rev 4.0.0.0 (2005/12/31) エラー発生時でも異常終了させずに処理を続けます。
    165         *
    166         * @param   val 設定値
    167         */
    168        public void setValue( final String val ) {
    169                if( !useInclude ) {
    170                        try {
    171                                value = getRequestParameter( val );
    172                        }
    173                        catch( HybsSystemException ex ) {
    174                                value = val ;
    175                                LogWriter.log( "val=" + val + " [" + ex.getMessage() + "]" );
    176                        }
    177                }
    178        }
    179
    180        /**
    181         * 【TAG】リクエスト情報の HTMLTag開始/終了文字(&gt;&lt;) 存在チェックを実施するかどうか[true/false]を設定します
    182         *              (初期値:USE_XSS_CHECK[={@og.value org.opengion.hayabusa.common.SystemData#USE_XSS_CHECK}])。
    183         *
    184         * @og.tag
    185         * クロスサイトスクリプティング(XSS)対策の一環としてless/greater than signについてのチェックを行います。
    186         * (&gt;&lt;) が含まれていたエラーにする(true)／かノーチェックか(false)を指定します。
    187         * (初期値:システム定数のUSE_XSS_CHECK[={@og.value org.opengion.hayabusa.common.SystemData#USE_XSS_CHECK}])。
    188         *
    189         * @og.rev 5.9.10.5 (2016/07/22) xssCheck
    190         *
    191         * @param       flag    XSSチェック [true:する/false:しない]
    192         * @see         org.opengion.hayabusa.common.SystemData#USE_XSS_CHECK
    193         */
    194        public void setXssCheck( final String flag ) {
    195                xssCheck = nval( getRequestParameter( flag ),xssCheck );
    196        }
    197
    198        /**
    199         * 【TAG】動的にファイルを include します。
    200         *
    201         * @og.tag
    202         * 指定のファイル名は、自身のディレクトリからの相対パスで表されます。
    203         *
    204         * @og.rev 4.0.0.0 (2007/05/25) 新規追加
    205         *
    206         * @param   file ファイル名
    207         */
    208        public void setInclude( final String file ) {
    209                useInclude = true;
    210
    211                String relativePath = getRequestParameter( file );
    212                String resourcePath = getContextRelativePath(getRequest(), relativePath);
    213                String realPath = HybsSystem.url2dir( resourcePath.substring(1) );
    214
    215                FileString fs = new FileString();
    216                fs.setFilename( realPath );
    217                value = fs.getValue();
    218        }
    219
    220        /**
    221         * このオブジェクトの文字列表現を返します。
    222         * 基本的にデバッグ目的に使用します。
    223         *
    224         * @return このクラスの文字列表現
    225         */
    226        @Override
    227        public String toString() {
    228                return org.opengion.fukurou.util.ToString.title( this.getClass().getName() )
    229                                .println( "VERSION"             ,VERSION        )
    230                                .println( "value"               ,value          )
    231                                .println( "Other..."    ,getAttributes().getAttribute() )
    232                                .fixForm().toString() ;
    233        }
    234
    235        /**
    236         * 動的にファイルを include する為の、コンテキストパスを求めます。
    237         *
    238         * 指定のファイル名は、自身のディレクトリからの相対パスで表されます。
    239         *
    240         * @og.rev 4.0.0.0 (2007/05/25) 新規追加
    241         * @og.rev 4.0.0.0 (2007/11/30) if の評価方法を変更します。
    242         *
    243         * @param       request                 ServletRequestオブジェクト
    244         * @param       relativePath    ファイル名
    245         *
    246         * @return      コンテキストパス
    247         */
    248        private String getContextRelativePath( final ServletRequest request,
    249                                                                                        final String relativePath) {
    250                if(relativePath.startsWith("/")) {
    251                        return (relativePath);
    252                }
    253                if(!(request instanceof HttpServletRequest)) {
    254                        return (relativePath);
    255                }
    256                HttpServletRequest hrequest = (HttpServletRequest) request;
    257                String uri = (String)request.getAttribute("javax.servlet.include.servlet_path");
    258//              if(uri != null) {
    259//                      String pathInfo = (String)request.getAttribute("javax.servlet.include.path_info");
    260//                      if(pathInfo == null) {
    261//                              if(uri.lastIndexOf('/') >= 0) {
    262//                                      uri = uri.substring(0, uri.lastIndexOf('/'));
    263//                              }
    264//                      }
    265//              }
    266                if( uri != null && uri.lastIndexOf('/') >= 0 ) {
    267                        String pathInfo = (String)request.getAttribute("javax.servlet.include.path_info");
    268                        if(pathInfo == null) {
    269                                uri = uri.substring(0, uri.lastIndexOf('/'));
    270                        }
    271                }
    272                else {
    273                        uri = hrequest.getServletPath();
    274                        if(uri.lastIndexOf('/') >= 0) {
    275                                uri = uri.substring(0, uri.lastIndexOf('/'));
    276                        }
    277                }
    278                return uri + '/' + relativePath;
    279        }
    280}