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