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.ToString;
021
022import static org.opengion.fukurou.util.StringUtil.nval;
023
024/**
025 * IorQueryTag にパラメーターを渡す為のタグクラスです。
026 *
027 * キーは、SQL文のselect句/where句/group by句/order by句が指定できます。
028 * 値は、value 属性で指定するか、なければ BODY 部に記述します。
029 *
030 * @og.formSample
031 * ●形式:
032 *     <og:iorQueryParam key="where" value="{'PN':'{@PN}%','TANI':'{@TANI}'}" />
033 *
034 * ●body:あり(EVAL_BODY_BUFFERED:BODYを評価し、{@XXXX} を解析します)
035 *
036 * ●Tag定義:
037 *   <og:iorQueryParam
038 *       key              ○【TAG】パラメータとして渡すキー情報を指定します (必須)
039 *       value              【TAG】パラメータとして渡す設定値を指定します (初期値:null)
040 *       quotCheck          【TAG】リクエスト情報の シングルクォート(') 存在チェックを実施するかどうか[true/false]を設定します (初期値:USE_SQL_INJECTION_CHECK[=true])
041 *       xssCheck           【TAG】リクエスト情報の HTMLTag開始/終了文字(><) 存在チェックを実施するかどうか[true/false]を設定します (初期値:USE_XSS_CHECK[=true])
042 *       caseKey            【TAG】このタグ自体を利用するかどうかの条件キーを指定します (初期値:null)
043 *       caseVal            【TAG】このタグ自体を利用するかどうかの条件値を指定します (初期値:null)
044 *       caseNN             【TAG】指定の値が、null/ゼロ文字列 でない場合(Not Null=NN)は、このタグは使用されます (初期値:判定しない)
045 *       caseNull           【TAG】指定の値が、null/ゼロ文字列 の場合は、このタグは使用されます (初期値:判定しない)
046 *       caseIf             【TAG】指定の値が、true/TRUE文字列の場合は、このタグは使用されます (初期値:判定しない)
047 *       debug              【TAG】デバッグ情報を出力するかどうか[true/false]を指定します (初期値:false)
048 *   >   ... Body ...
049 *   </og:iorQueryParam>
050 *
051 * ●使用例
052 *     <og:iorQuery
053 *         url           = "http://・・・ "
054 *         authURL       = "http://・・・ "
055 *         authUserPass  = "admin:******"
056 *         appliName     = "データテーブル名"
057 *         callMethod    = "getReportInfo"
058 *     >
059 *         <og:iorQueryParam
060 *             key  = "select"  value  = "PN,TANI,count(*) as CNT"  />
061 *         <og:iorQueryParam
062 *             key  = "where"  >
063 *             {'PN':'{@PN}%','TANI':'{@TANI}'}
064 *         </og:iorQueryParam
065 *     </og:iorQuery ・・・・・ >
066 *
067 * @og.rev 8.0.2.0 (2021/11/30) 新規作成
068 * @og.group その他部品
069 *
070 * @version  8.0
071 * @author   LEE.M
072 * @since    JDK17.0,
073 */
074public class IorQueryParamTag extends CommonTagSupport {
075        /** このプログラムのVERSION文字列を設定します。 {@value} */
076        private static final String VERSION = "8.0.2.0 (2021/11/30)" ;
077        private static final long serialVersionUID = 802020211130L ;
078
079        private String  key                     ;                                                                                                       // キー情報
080        private String  value           ;                                                                                                       // 設定値
081        private boolean quotCheck       = HybsSystem.sysBool( "USE_SQL_INJECTION_CHECK" );      // クオートチェック
082        private boolean xssCheck        = HybsSystem.sysBool( "USE_XSS_CHECK" );                        // XSSチェック
083
084        /**
085         * デフォルトコンストラクター
086         */
087        public IorQueryParamTag() { super(); }  // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。
088
089        /**
090         * Taglibの開始タグが見つかったときに処理する doStartTag() を オーバーライドします。
091         *
092         * @return      後続処理の指示
093         */
094        @Override
095        public int doStartTag() {
096                if( useTag() ) {
097                        useQuotCheck( quotCheck );
098                        useXssCheck( xssCheck );
099
100                        value = getRequestParameter( value );
101
102                        if( value == null || value.isEmpty() ) {
103                                return EVAL_BODY_BUFFERED;                                                                              // Body を評価する。( extends BodyTagSupport 時)
104                        }
105                }
106                return SKIP_BODY;                                                                                                               // Body を評価しない
107        }
108
109        /**
110         * Taglibのタグ本体を処理する doAfterBody() を オーバーライドします。
111         *
112         * @return      後続処理の指示(SKIP_BODY)
113         */
114        @Override
115        public int doAfterBody() {
116                value = getBodyString();
117                return SKIP_BODY ;
118        }
119
120        /**
121         * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。
122         *
123         * @return      後続処理の指示
124         */
125        @Override
126        public int doEndTag() {
127                debugPrint();
128                if( useTag() ) {
129                        final IorQueryTag iorQuery = (IorQueryTag)findAncestorWithClass( this,IorQueryTag.class );
130                        if( iorQuery == null ) {
131                                final String errMsg = "<b>" + getTagName() + "タグは、IorQueryTagの内側(要素)に記述してください。</b>";
132                                throw new HybsSystemException( errMsg );
133                        }
134                        iorQuery.addParam( key, value );
135                }
136                return EVAL_PAGE ;
137        }
138
139        /**
140         * タグリブオブジェクトをリリースします。
141         * キャッシュされて再利用されるので、フィールドの初期設定を行います。
142         *
143         */
144        @Override
145        protected void release2() {
146                super.release2();
147                key                     = null;                                                                                                         // キー情報
148                value           = null;                                                                                                         // 設定値
149                quotCheck       = HybsSystem.sysBool( "USE_SQL_INJECTION_CHECK" );                      // クオートチェック
150                xssCheck        = HybsSystem.sysBool( "USE_XSS_CHECK" );                                        // XSSチェック
151        }
152
153        /**
154         * 【TAG】パラメータとして渡すキー情報を指定します。
155         *
156         * @og.tag
157         * IorQuery に渡すパラメータのキー情報です。
158         * 値は、value 属性で指定するか、なければ BODY 部に記述します。
159         *
160         * キーは、SQL文のselect句/where句/group by句/order by句が指定できます。
161         *
162         * 処理対象を特定するカラム名(select句)が指定できます。
163         *   SQL文:  select  PN,TANI,count(*) as CNT
164         *   使用文: key="select"  value="PN,TANI,count(*) as CNT"
165         *
166         * 処理対象を特定するキー条件(where句)が指定できます。
167         *   (1) SQL文:  where  PN LIKE 'GEN%'  and  TANI = 'KG'
168         *       使用文: key="where"     value="{'PN':'GEN%','TANI':'KG'}"
169         *   (2) SQL文:  where  DYSET &gt;= '20211101'
170         *       使用文: key="where_ge"  value="{'DYSET':'20211101'}"
171         *   (3) SQL文:  where  DYSET &lt;= '20211101'
172         *       使用文: key="where_le"  value="{'DYSET':'20211101'}"
173         *
174         * 処理対象を特定する集計条件(group by句)が指定できます。
175         *   SQL文:  group by  PN,TANI
176         *   使用文: key="group by"  value="PN,TANI"
177         *
178         * 処理対象の並び替えを指定するキーワード(order by句)が指定できます。
179         *   SQL文:  order by  PN,TANI
180         *   使用文: key="order_by"  value="PN,TANI"
181         *
182         * @param       prmKey  キー情報
183         */
184        public void setKey( final String prmKey ) {
185                key = nval( getRequestParameter( prmKey ),key );
186                if( key == null ) {
187                        final String errMsg = "key がセットされていません。";
188                        throw new HybsSystemException( errMsg );
189                }
190        }
191
192        /**
193         * 【TAG】パラメータとして渡す設定値を指定します(初期値:null)。
194         *
195         * @og.tag
196         * IorQuery に渡すパラメータの設定値です。
197         * 値は、value 属性で指定するか、なければ BODY 部に記述します。
198         * BODY 部に記述された場合は、文字列を trim() します。
199         * 設定値は、value 属性が優先です。ここの値が、null の場合は、
200         * BODY 要素を値として使用します。
201         *
202         * @param       val     設定値
203         * @see         #setKey( String )
204         */
205        public void setValue( final String val ) {
206                value = nval( getRequestParameter( val ),value );
207        }
208
209        /**
210         * 【TAG】リクエスト情報の シングルクォート(') 存在チェックを実施するかどうか[true/false]を設定します
211         *        (初期値:USE_SQL_INJECTION_CHECK[={@og.value SystemData#USE_SQL_INJECTION_CHECK}])。
212         *
213         * @og.tag
214         * SQLインジェクション対策の一つとして、暫定的ではありますが、SQLのパラメータに
215         * 渡す文字列にシングルクォート(') を許さない設定にすれば、ある程度は防止できます。
216         * 数字タイプの引数には、 or 5=5 などのシングルクォートを使用しないコードを埋めても、
217         * 数字チェックで検出可能です。文字タイプの場合は、必ず (')をはずして、
218         * ' or 'A' like 'A のような形式になる為、(')チェックだけでも有効です。
219         * (') が含まれていたエラーにする(true)/かノーチェックか(false)を指定します。
220         * (初期値:システム定数のUSE_SQL_INJECTION_CHECK[={@og.value SystemData#USE_SQL_INJECTION_CHECK}])。
221         *
222         * @param       flag クォートチェック [true:する/それ以外:しない]
223         * @see         org.opengion.hayabusa.common.SystemData#USE_SQL_INJECTION_CHECK
224         */
225        public void setQuotCheck( final String flag ) {
226                quotCheck = nval( getRequestParameter( flag ),quotCheck );
227        }
228
229        /**
230         * 【TAG】リクエスト情報の HTMLTag開始/終了文字(&gt;&lt;) 存在チェックを実施するかどうか[true/false]を設定します
231         *        (初期値:USE_XSS_CHECK[={@og.value SystemData#USE_XSS_CHECK}])。
232         *
233         * @og.tag
234         * クロスサイトスクリプティング(XSS)対策の一環としてless/greater than signについてのチェックを行います。
235         * (&gt;&lt;) が含まれていたエラーにする(true)/かノーチェックか(false)を指定します。
236         * (初期値:システム定数のUSE_XSS_CHECK[={@og.value SystemData#USE_XSS_CHECK}])。
237         *
238         * @param       flag    XSSチェック [true:する/false:しない]
239         * @see         org.opengion.hayabusa.common.SystemData#USE_XSS_CHECK
240         */
241        public void setXssCheck( final String flag ) {
242                xssCheck = nval( getRequestParameter( flag ),xssCheck );
243        }
244
245        /**
246         * このオブジェクトの文字列表現を返します。
247         * 基本的にデバッグ目的に使用します。
248         *
249         * @return      このクラスの文字列表現
250         * @og.rtnNotNull
251         */
252        @Override
253        public String toString() {
254                return ToString.title( this.getClass().getName() )
255                                .println( "VERSION"             ,VERSION        )
256                                .println( "key"                 ,key            )
257                                .println( "value"               ,value          )
258                                .println( "quotCheck"   ,quotCheck      )
259                                .println( "Other..."    ,getAttributes().getAttribute() )
260                                .fixForm().toString() ;
261        }
262}