    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.ToString;                                              // 6.1.1.0 (2015/01/17)
    019
    020import static org.opengion.fukurou.util.StringUtil.nval ;
    021
    022/**
    023 * switch タグは、指定された条件を、case タグに伝えます。
    024 *
    025 * 各属性は、{&#064;XXXX} 変数が使用できます。
    026 * これは、ServletRequest から、XXXX をキーに値を取り出し,この変数に
    027 * 割り当てます。つまり、このXXXXをキーにリクエストすれば、
    028 * この変数に値をセットすることができます。
    029 *
    030 * @og.formSample
    031 * ●形式：&lt;og:switch key="･･･" &gt;
    032 *            &lt;og:case match="A" &gt; ･･･ &lt;/og:case&gt;
    033 *            &lt;og:case match="B" &gt; ･･･ &lt;/og:case&gt;
    034 *            &lt;og:case match="C" &gt; ･･･ &lt;/og:case&gt;
    035 *            &lt;og:case isDefault="true" &gt; ･･･ &lt;/og:case&gt;
    036 *         &lt;/og:switch&gt;
    037 * ●body：あり(EVAL_BODY_INCLUDE:BODYをインクルードし、{&#064;XXXX} は解析しません)
    038 *
    039 * ●Tag定義：
    040 *   &lt;og:switch
    041 *       key              ○【TAG】switch のマッチ判定用のキーを設定します(必須)。
    042 *       debug              【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false)
    043 *   &gt;   ... Body ...
    044 *   &lt;/og:switch&gt;
    045 *
    046 * ●使用例
    047 *         &lt;og:switch key="{&#064;PARAM}" &gt;
    048 *            &lt;og:case match="A" &gt; 処理A &lt;/og:case&gt;
    049 *            &lt;og:case match="B" &gt; 処理B &lt;/og:case&gt;
    050 *            &lt;og:case match="C" &gt; 処理C &lt;/og:case&gt;
    051 *            &lt;og:case isDefault="true" &gt; 処理X &lt;/og:case&gt;
    052 *         &lt;/og:switch&gt;
    053 *
    054 *          ・switch の key に対して、case の match に指定された値が、マッチ(switch_key.match( case_match ))
    055 *            した場合に、case の BODY 部分が処理されます。
    056 *            マッチしなければ、BODY部は、スキップされます。
    057 *          ・isDefault="true" の場合は、どれとも マッチしなかった場合に、実行されます。
    058 *          ・Javaの switch-case 文は、最初に処理された case 以降を処理します。通常は、break を入れて
    059 *            後続処理を実行されないようにしています。
    060 *            この、switch-case タグは、caseタグの isBreak 属性で制御します。初期値が isBreak="true" に、
    061 *            なっているため、通常は、どれかの case が実行された段階で、switchの処理は、終了されます。
    062 *            isBreak="false" にすると、switchから抜けずに、継続して case との match を実行します。
    063 *            この場合、Java等と異なるのは、直後のcase文が実行されるのではなく、あくまで match 作業が
    064 *            継続されるということです。つまり、複数の case で処理を行いたい場合は、isBreak="false" に
    065 *            すると同時に、match 条件もそれぞれで、マッチするように設定する必要があります。
    066 *
    067 *         &lt;og:switch key="{&#064;PARAM}" &gt;
    068 *            &lt;og:case match="[1]"   isBreak="false" &gt; 処理A &lt;/og:case&gt;
    069 *            &lt;og:case match="[12]"  isBreak="false" &gt; 処理B &lt;/og:case&gt;
    070 *            &lt;og:case match="[123]" isBreak="false" &gt; 処理C &lt;/og:case&gt;
    071 *            &lt;og:case isNull="true" &gt; 処理X &lt;/og:case&gt;
    072 *            &lt;og:case isDefault="true" &gt; 処理Y &lt;/og:case&gt;
    073 *         &lt;/og:switch&gt;
    074 *
    075 *          ・上記指定では、isBreak="false" が指定されているため、マッチした後も継続して判定処理が実施されます。
    076 *          ・上記例で言うと、PARAM が "1" の場合、上記３つともにマッチします。
    077 *          ・isNull="true" は、switch の key が null の場合に成立します。(null とは、ゼロ文字列も含む)
    078 *
    079 * @og.group 画面制御
    080 * @og.rev 5.2.3.0 (2010/12/01) 新規追加
    081 *
    082 * @version  5.2.3.0 (2010/12/01)
    083 * @author       Kazuhiko Hasegawa
    084 * @since    JDK1.6,
    085 */
    086public class SwitchTag extends CommonTagSupport {
    087        /** このプログラムのVERSION文字列を設定します。   {@value} */
    088        private static final String VERSION = "6.4.2.0 (2016/01/29)" ;
    089        private static final long serialVersionUID = 642020160129L ;
    090
    091        private String  switchKey       ;
    092        private boolean useMatch        = true;         // マッチ処理を継続して行う場合、true  (5.3.0.0 (2010/12/01) 変数名変更)
    093
    094        /**
    095         * デフォルトコンストラクター
    096         *
    097         * @og.rev 6.4.2.0 (2016/01/29) PMD refactoring. Each class should declare at least one constructor.
    098         */
    099        public SwitchTag() { super(); }         // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。
    100
    101        /**
    102         * Taglibの開始タグが見つかったときに処理する doStartTag() を オーバーライドします。
    103         *
    104         * @return      後続処理の指示( EVAL_BODY_INCLUDE )
    105         */
    106        @Override
    107        public int doStartTag() {
    108                useMatch        = true; // 初期化
    109
    110                return EVAL_BODY_INCLUDE ;      // Body インクルード( extends TagSupport 時)
    111        }
    112
    113        /**
    114         * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。
    115         *
    116         * @return      後続処理の指示
    117         */
    118        @Override
    119        public int doEndTag() {
    120                debugPrint();
    121
    122                return EVAL_PAGE ;
    123        }
    124
    125        /**
    126         * タグリブオブジェクトをリリースします。
    127         * キャッシュされて再利用されるので、フィールドの初期設定を行います。
    128         *
    129         */
    130        @Override
    131        protected void release2() {
    132                super.release2();
    133                switchKey       = null;
    134                useMatch        = true;
    135        }
    136
    137        /**
    138         * 【TAG】switch のマッチ判定用のキーを設定します。
    139         *
    140         * @og.tag switch のマッチ判定用のキーを設定します。
    141         *
    142         * @param       key マッチ判定用のキー
    143         * @see         #getKey()
    144         */
    145        public void setKey( final String key ) {
    146                switchKey = nval( getRequestParameter( key ),switchKey );
    147        }
    148
    149        /**
    150         * switch のマッチ判定用のキーを取得します。
    151         *
    152         * case タグで、この値を取り出して、マッチ判定を行います。
    153         *
    154         * @return      マッチ判定用のキー
    155         * @see         #setKey( String )
    156         */
    157        protected String getKey() {
    158                return switchKey;
    159        }
    160
    161        /**
    162         * case タグが、ブレイクした場合に、このメソッドを呼び出します。
    163         *
    164         * これは、 case タグが isBreak="true" でマッチした場合、このメソッドを
    165         * 呼び出し、isMatch フラグを false に設定します。
    166         * 他の case は、このフラグを参照して、false であれば、スルーします。
    167         *
    168         * @see         #isMatch()
    169         */
    170        protected void setBreak() {
    171                useMatch= false ;
    172        }
    173
    174        /**
    175         * すでにマッチしたかどうかを返します。
    176         *
    177         * これは、 case タグが 処理を継続するかどうかの判定に利用します。
    178         * case タグが isBreak="true" でマッチした場合、isMatch フラグは、
    179         * false が返りますので、継続処理しません。
    180         *
    181         * @return      マッチしたかどうか[true:継続判定/false:スルー]
    182         * @see         #setBreak()
    183         */
    184        protected boolean isMatch() {
    185                return useMatch ;
    186        }
    187
    188        /**
    189         * このオブジェクトの文字列表現を返します。
    190         * 基本的にデバッグ目的に使用します。
    191         *
    192         * @return このクラスの文字列表現
    193         * @og.rtnNotNull
    194         */
    195        @Override
    196        public String toString() {
    197                return ToString.title( this.getClass().getName() )
    198                                .println( "VERSION"                     ,VERSION        )
    199                                .println( "switchKey"           ,switchKey      )
    200                                .println( "Other..."    ,getAttributes().getAttribute() )
    201                                .fixForm().toString() ;
    202        }
    203}