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