    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.fukurou.util.Attributes;
    019import org.opengion.fukurou.util.ToString;                                              // 6.1.1.0 (2015/01/17)
    020import static org.opengion.fukurou.system.HybsConst.CR ;                        // 6.2.4.0 (2015/05/15)
    021
    022import java.util.List;
    023import java.util.ArrayList;
    024
    025/**
    026 * and タグで指定された条件を元に、WHERE句を作成します。
    027 *
    028 * 各属性は、{&#064;XXXX} 変数が使用できます。
    029 * これは、ServletRequest から、XXXX をキーに値を取り出し、この変数に
    030 * 割り当てます。つまり、このXXXXをキーにリクエストすれば、
    031 * この変数に値をセットすることができます。
    032 *
    033 * @og.formSample
    034 * ●形式：&lt;og:where startKey="…" &gt; &lt;og:and startKey="…" ... /&gt; &lt;/og:where&gt;
    035 * ●body：あり(EVAL_BODY_INCLUDE:BODYをインクルードし、{&#064;XXXX} は解析しません)
    036 *
    037 * ●Tag定義：
    038 *   &lt;og:where
    039 *       startKey           【TAG】SQL条件句の最初の演算子を指定します(初期値:where)
    040 *       debug              【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false)
    041 *   &gt;   ... Body ...
    042 *   &lt;/og:where&gt;
    043 *
    044 * ●使用例
    045 *     &lt;og:query command="NEW"&gt;
    046 *             select PN,YOBI,NMEN,HINM from XX01 where PN = '{&#064;PN}' order by PN
    047 *     &lt;/og:query&gt;
    048 *
    049 *          ・検索条件が入力された時({&#064;PN}がNOT NULLのとき)
    050 *            作成されるSQL文⇒select PN,YOBI,NMEN,HINM from XX01 where PN = 'AAA' order by PN
    051 *          ・検索条件が入力されなかった時({&#064;PN}がNULLのとき)
    052 *            作成されるSQL文⇒select PN,YOBI,NMEN,HINM from XX01 where PN = '' order by PN
    053 *
    054 *     &lt;og:query command="NEW"&gt;
    055 *             select PN,YOBI,NMEN,HINM from XX01
    056 *         &lt;og:where&gt;
    057 *             &lt;og:and value="PN = '{&#064;PN}%'" /&gt;
    058 *             &lt;og:and value="YOBI like '{&#064;YOBI}%'" /&gt;
    059 *         &lt;/og:where&gt;
    060 *             order by PN
    061 *     &lt;/og:query&gt;
    062 *
    063 *          ・検索条件が入力された時({&#064;PN}がNOT NULLのとき)
    064 *            作成されるSQL文⇒select PN,YOBI,NMEN,HINM from XX01 PN = 'AAA%' and YOBI like 'BBB%' order by PN
    065 *          ・検索条件が入力されなかった時({&#064;PN}がNULLのとき) WHERE句がなくなる。
    066 *            作成されるSQL文⇒select PN,YOBI,NMEN,HINM from XX01 order by PN
    067 *
    068 *        注意:WhereTagを使った場合、下のようにはなりません。
    069 *            select PN,YOBI,NMEN,HINM from XX01 PN = '' and YOBI like '%' order by PN
    070 *
    071 *     &lt;og:query command="NEW"&gt;
    072 *             select PN,YOBI,NMEN,HINM from XX01 where PN="11111"
    073 *         &lt;og:where startKey="and"&gt;
    074 *             &lt;og:and value="YOBI like '{&#064;PN}%'" /&gt;
    075 *         &lt;/og:where&gt;
    076 *             order by PN
    077 *     &lt;/og:query&gt;
    078 *
    079 *          ・検索条件が入力された時({&#064;YOBI}がNOT NULLのとき)
    080 *            作成されるSQL文⇒select PN,YOBI,NMEN,HINM from XX01 PN = '11111' and YOBI like 'BBB%' order by PN
    081 *          ・検索条件が入力されなかった時({&#064;YOBI}がNULLのとき) WHERE句がなくなる。
    082 *            作成されるSQL文⇒select PN,YOBI,NMEN,HINM from XX01 PN = '11111' order by PN
    083 *
    084 * @og.group 画面部品
    085 *
    086 * @version  4.0
    087 * @author       Kazuhiko Hasegawa
    088 * @since    JDK5.0,
    089 */
    090public class SqlWhereTag extends CommonTagSupport {
    091        /** このプログラムのVERSION文字列を設定します。   {@value} */
    092        private static final String VERSION = "6.4.2.0 (2016/01/29)" ;
    093        private static final long serialVersionUID = 642020160129L ;
    094
    095        private transient List<Attributes>      values  ;
    096
    097        private String  startKey        = "where";
    098        private String  whereWord       = "";
    099
    100        /**
    101         * デフォルトコンストラクター
    102         *
    103         * @og.rev 6.4.2.0 (2016/01/29) PMD refactoring. Each class should declare at least one constructor.
    104         */
    105        public SqlWhereTag() { super(); }               // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。
    106
    107        /**
    108         * Taglibの開始タグが見つかったときに処理する doStartTag() を オーバーライドします。
    109         *
    110         * @return      後続処理の指示( EVAL_BODY_INCLUDE )
    111         */
    112        @Override
    113        public int doStartTag() {
    114                return EVAL_BODY_INCLUDE ;      // Body インクルード( extends TagSupport 時)
    115        }
    116
    117        /**
    118         * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。
    119         *
    120         * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。release2() を doEndTag()で呼ぶ。
    121         *
    122         * @return      後続処理の指示
    123         */
    124        @Override
    125        public int doEndTag() {
    126                debugPrint();           // 4.0.0 (2005/02/28)
    127                jspPrint( makeSqlWhere() );
    128
    129                return EVAL_PAGE ;
    130        }
    131
    132        /**
    133         * タグリブオブジェクトをリリースします。
    134         * キャッシュされて再利用されるので、フィールドの初期設定を行います。
    135         *
    136         * @og.rev 2.0.0.4 (2002/09/27) カスタムタグの release() メソッドを、追加
    137         * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。release2() を doEndTag()で呼ぶ。
    138         *
    139         */
    140        @Override
    141        protected void release2() {
    142                super.release2();
    143                values          = null;
    144                startKey        = "where";
    145                whereWord       = "";
    146        }
    147
    148        /**
    149         * 内部タグの SqlAndTag / SqlAndTag より、個々のカラムの値を書き換える
    150         * 為のアトリビュートを受け取る。
    151         *
    152         * 複数の値を受け取って、後ほど、すべてのカラムに対して処理を行います。
    153         *
    154         * @og.rev 3.1.0.0 (2003/03/20) Vector を使用している箇所で、非同期でも構わない箇所を、ArrayList に置換え。
    155         * @og.rev 3.1.2.0 (2003/04/07) taglib パッケージ内部で使用している箇所を protected 化する。
    156         *
    157         * @param   attri       属性リスト
    158         */
    159        protected void setAttributes( final Attributes attri ) {
    160                if( values == null ) { values = new ArrayList<>(); }
    161                values.add( attri );
    162        }
    163
    164        /**
    165         * 【TAG】SQL条件句の最初の演算子を指定します(初期値:where)。
    166         *
    167         * @og.tag SQL条件句の最初の演算子を指定します。
    168         *
    169         * @param       skey 条件句の最初の演算子
    170         */
    171        public void setStartKey( final String skey ) {
    172                final String key = getRequestParameter( skey );
    173                if( key != null && key.length() > 0 ) { startKey = key; }
    174        }
    175
    176        /**
    177         * SqlAndTag / SqlOrTag で指定された条件を元に、WHERE句を作成します。
    178         *
    179         * @og.rev 6.2.4.0 (2015/05/15) 各andの終わりに、改行とTABを出力します。
    180         *
    181         * @return      WHERE句の文字列
    182         */
    183        private String makeSqlWhere() {
    184                final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE );
    185                if( values != null ) {
    186                        for( int i=0; i<values.size(); i++ ) {
    187                                final Attributes attri = values.get( i );
    188                                String keyWord = attri.get( "keyWord" );
    189                                final String value = attri.get( "value" );
    190                                if( buf.length() == 0 ) { keyWord = this.startKey; }
    191                                buf.append( '\t' )                      // 6.2.4.0 (2015/05/15) debug時のレイアウト考慮
    192                                        .append( keyWord )
    193                                        .append( ' ' )                  // 6.0.2.5 (2014/10/31) char を append する。
    194                                        .append( value )
    195                                        .append( CR );                  // 6.2.4.0 (2015/05/15) debug時のレイアウト考慮
    196                        }
    197                }
    198                whereWord = buf.toString();
    199                return whereWord;
    200        }
    201
    202        /**
    203         * タグの名称を、返します。
    204         * 自分自身のクラス名より、自動的に取り出せないため、このメソッドをオーバーライドします。
    205         *
    206         * @og.rev 4.0.0.0 (2005/01/31) 新規追加
    207         *
    208         * @return  タグの名称
    209         * @og.rtnNotNull
    210         */
    211        @Override
    212        protected String getTagName() {
    213                return "where" ;
    214        }
    215
    216        /**
    217         * このオブジェクトの文字列表現を返します。
    218         * 基本的にデバッグ目的に使用します。
    219         *
    220         * @return このクラスの文字列表現
    221         * @og.rtnNotNull
    222         */
    223        @Override
    224        public String toString() {
    225                return ToString.title( this.getClass().getName() )
    226                                .println( "VERSION"                     ,VERSION        )
    227                                .println( "startKey"            ,startKey       )
    228                                .println( "whereWord"           ,whereWord      )
    229                                .println( "Other..."    ,getAttributes().getAttribute() )
    230                                .fixForm().toString() ;
    231        }
    232}