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