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     */
016    package org.opengion.hayabusa.taglib;
017    
018    import org.opengion.hayabusa.common.HybsSystemException;
019    import static org.opengion.fukurou.util.StringUtil.nval ;
020    
021    /**
022     * case タグは、上位ã? switch タグの key とマッチしたå?合に、å?ç�?‚’行いますã?
023     *
024     * case タグの以下ã?属æ?につã�?�¦、説明しますã?
025     *   match    ??switch_key.match( case_match ) でマッチしたå?合ã?、BODY がå?ç�?�•れますã?
026     *   isDefault??trueに設定すると、どのcase にもã?ãƒ?ƒ�しなかったå?合に処ç�?�•れまã�?初期値:false)
027     *   isBreak  ??通常、最初にマッチした段階で、switch 処ç�?‚’抜けまã�?初期値:true)
028     *   isNull   ??trueに設定すると、switchのkeyがã?null(またã?ゼロæ–?­—å?)の場合ã?マッチしまã�?初期値:false)
029     *
030     * @og.formSample
031     * ●形式ï¼?lt;og:switch key="?¥?¥?¥" />
032     *            <og:case match="A" /> ?¥?¥?¥ </og:case>
033     *            <og:case match="B" /> ?¥?¥?¥ </og:case>
034     *            <og:case match="C" /> ?¥?¥?¥ </og:case>
035     *            <og:case isDefault="true" /> ?¥?¥?¥ </og:case>
036     *         </og:switch>
037     * ●body?šあã‚?EVAL_BODY_INCLUDE:BODYをインクルードし、{@XXXX} は解析しません)
038     *
039     * ●Tag定義??
040     *   <og:case
041     *       match              【TAG】switch-case のマッチ条件(case_match)を指定しまã�?
042     *       isDefault          【TAG】どのcase にもã?ãƒ?ƒ�しなかったå?合に処ç�?�™ã‚?case æ–?�‹どã�?�‹を指定しまã�?初期値:false)
043     *       isBreak            【TAG】ã?ãƒ?ƒ�した以降に継続å?ç�?‚’行わなã�?ブレイクする)かどã�?�‹を指å®?初期値:true)
044     *       isNull             【TAG】switchのkeyがã?null(またã?ゼロæ–?­—å?)の場合ã?マッチするかどã�?�‹[true/false]を設定しまã�?初期値:false)
045     *       debug              【TAG】デバッグæƒ??をå?力するかどã�?�‹[true/false]を指定しまã�?初期値:false)
046     *   >   ... Body ...
047     *   </og:case>
048     *
049     * ●使用ä¾?
050     *         <og:switch key="{@PARAM}" />
051     *            <og:case match="A" /> 処ç�? </og:case>
052     *            <og:case match="B" /> 処ç�? </og:case>
053     *            <og:case match="C" /> 処ç�? </og:case>
054     *            <og:case isDefault="true" /> 処ç�? </og:case>
055     *         </og:switch>
056     *
057     *          ・switch の key に対して、case の match にæŒ?®šされた値がã?マッãƒ?switch_key.match( case_match ))
058     *            した場合に、case の BODY 部åˆ?�Œ処ç�?�•れますã?
059     *            マッチしなければ、BODY部は、スキãƒ??されますã?
060     *          ・isDefault="true" の場合ã?、どれとã‚?マッチしなかったå?合に、実行されますã?
061     *          ・Javaの switch-case æ–??、最初に処ç�?�•れた case 以降を処ç�?�—ますã?通常は、break をå?れて
062     *            後続å?ç�?‚’実行されなã�?‚ˆã�?�«してã�?�¾すã?
063     *            こã?、switch-case タグは、caseタグの isBreak 属æ?で制御しますã?初期値ã�?isBreak="true" にã€?
064     *            なってã�?‚‹ためã€??常は、どれかの case が実行された段階で、switchの処ç�??、終äº?�•れますã?
065     *            isBreak="false" にすると、switchから抜けずに、継続して case との match を実行しますã?
066     *            こã?場合ã?Java等と異なるã?は、直後ã?caseæ–?�Œ実行されるのではなくã?あくまで match 作業ã�?
067     *            継続されるとã�?�†ことですã?つまりã?è¤?•°の case で処ç�?‚’行いたい場合ã?、isBreak="false" に
068     *            すると同時に、match 条件もそれぞれで、ã?ãƒ?ƒ�するように設定するå¿?¦�がありますã?
069     *
070     *         <og:switch key="{@PARAM}" />
071     *            <og:case match="[1]"   isBreak="false" /> 処ç�? </og:case>
072     *            <og:case match="[12]"  isBreak="false" /> 処ç�? </og:case>
073     *            <og:case match="[123]" isBreak="false" /> 処ç�? </og:case>
074     *            <og:case isNull="true" /> 処ç�? </og:case>
075     *            <og:case isDefault="true" /> 処ç�? </og:case>
076     *         </og:switch>
077     *
078     *          ・上記指定では、isBreak="false" が指定されてã�?‚‹ため、ã?ãƒ?ƒ�した後も継続して判定å?ç�?�Œ実施されますã?
079     *          ・上記例でè¨?�†と、PARAM ã�?"1" の場合ã?上記3つともにマッチしますã?
080     *          ・isNull="true" は、switch の key ã�?null の場合に成立しますã?(null とは、ゼロæ–?­—å?も含ã‚?
081     *
082     * @og.group 画面制御
083     * @og.rev 5.2.3.0 (2010/12/01) 新規追åŠ?
084     *
085     * @version  5.2.3.0 (2010/12/01)
086     * @author       Kazuhiko Hasegawa
087     * @since    JDK1.6,
088     */
089    public class CaseTag extends CommonTagSupport {
090            //* こã?プログラãƒ??VERSIONæ–?­—å?を設定しますã?       {@value} */
091            private static final String VERSION = "5.2.3.0 (2010/12/01)" ;
092    
093            private static final long serialVersionUID = 523020101201L ;
094    
095            private String  caseMatch       = null ;        // switch_key.match( case_match ) でマッチしたå?合ã?、BODY がå?ç�?�•れますã?
096            private boolean isDefault       = false;        // trueに設定すると、どのcase にもã?ãƒ?ƒ�しなかったå?合に処ç�?�•れまã�?初期値:false)
097            private boolean isBreak         = true ;        // 通常、最初にマッチした段階で、switch 処ç�?‚’抜けまã�?初期値:true)
098            private boolean isNull          = false;        // trueに設定すると、switchのkeyがã?null(またã?ゼロæ–?­—å?)の場合ã?マッチしまã�?初期値:false)
099    
100            /**
101             * Taglibの開始タグが見つかったときに処ç�?�™ã‚?doStartTag() ã‚?オーバã?ライドしますã?
102             *
103             * @return      後続å?ç�??æŒ?¤º
104             */
105            @Override
106            public int doStartTag() {
107                    SwitchTag switchTag = (SwitchTag)findAncestorWithClass( this,SwitchTag.class );
108                    if( switchTag == null ) {
109    //                      String errMsg = "<b>こã?タグは、switch タグのå†?ƒ¨におくå¿?¦�がありますã?</b>";
110                            String errMsg = "<b>" + getTagName() + "タグは、switch タグのå†?ƒ¨におくå¿?¦�がありますã?</b>";
111                            throw new HybsSystemException( errMsg );
112                    }
113    
114                    boolean rtn = false;
115                    if( switchTag.isMatch() ) {
116                            String key = switchTag.getKey();
117                            rtn =   ( key != null && caseMatch != null && key.matches( caseMatch ) ) ||
118                                            ( isNull && key == null ) || ( isDefault ) ;
119    
120                            if( rtn && isBreak ) { switchTag.setBreak(); }
121                    }
122    
123                    if( rtn ) { return( EVAL_BODY_INCLUDE ); }
124                    else      { return( SKIP_BODY );         }
125            }
126    
127            /**
128             * Taglibの終äº?‚¿グが見つかったときに処ç�?�™ã‚?doEndTag() ã‚?オーバã?ライドしますã?
129             *
130             * @return      後続å?ç�??æŒ?¤º
131             */
132            @Override
133            public int doEndTag() {
134                    debugPrint();           // 4.0.0 (2005/02/28)
135    
136                    return(EVAL_PAGE);
137            }
138    
139            /**
140             * タグリブオブジェクトをリリースしますã?
141             * キャãƒ?‚·ュされて再利用されるã?で、フィールドã?初期設定を行いますã?
142             *
143             */
144            @Override
145            protected void release2() {
146                    super.release2();
147                    caseMatch       = null ;        // switch_key.match( case_match ) でマッチしたå?合ã?、BODY がå?ç�?�•れますã?
148                    isDefault       = false;        // trueに設定すると、どのcase にもã?ãƒ?ƒ�しなかったå?合に処ç�?�•れまã�?初期値:false)
149                    isBreak         = true ;        // 通常、最初にマッチした段階で、switch 処ç�?‚’抜けまã�?初期値:true)
150                    isNull          = false;        // trueに設定すると、switchのkeyがã?null(またã?ゼロæ–?­—å?)の場合ã?マッチしまã�?初期値:false)
151            }
152    
153            /**
154             * 【TAG】switch-case のマッチ条件(case_match)を指定しますã?
155             *
156             * @og.tag
157             * switch_key.match( case_match ) でマッチしたå?合ã?、BODY がå?ç�?�•れますã?
158             *
159             * @param       mkey マッチ条件
160             */
161            public void setMatch( final String mkey ) {
162                    caseMatch = nval( getRequestParameter( mkey ),caseMatch );
163            }
164    
165            /**
166             * 【TAG】どのcase にもã?ãƒ?ƒ�しなかったå?合に処ç�?�™ã‚?case æ–?�‹どã�?�‹を指定しまã�?初期値:false)ã€?
167             *
168             * @og.tag
169             * trueに設定すると、どのcase にもã?ãƒ?ƒ�しなかったå?合に処ç�?�•れまã�?
170             * こã?タグそã?もã?がなにもå?力しませんã€?つまり条件から消えますã?)
171             * BODY 部に記述することが可能ですã?そã?場合ã?、value 属æ?になにも設定できませんã€?
172             * 初期値は、false?šdefault case æ–?�§はなã�?ですã?
173             *
174             * @param       flag マッチしなかったå?合に処ç�?�™ã‚?case æ–?�‹どã�?�‹[true/false]
175             */
176            public void setIsDefault( final String flag ) {
177                    isDefault = nval( getRequestParameter( flag ),isDefault );
178            }
179    
180            /**
181             * 【TAG】ã?ãƒ?ƒ�した以降に継続å?ç�?‚’行わなã�?ブレイクする)かどã�?�‹を指å®?初期値:true)ã€?
182             *
183             * @og.tag
184             * true に設定すると、ã?ãƒ?ƒ�した段階で、ブレイクしますã?
185             * Javaの switch-case æ–??、最初に処ç�?�•れた case 以降を処ç�?�—ますã?通常は、break をå?れて
186             * 後続å?ç�?‚’実行されなã�?‚ˆã�?�«してã�?�¾すã?
187             * こã?、switch-case タグは、caseタグの break 属æ?で制御しますã?初期値ã�?break="true" にã€?
188             * なってã�?‚‹ためã€??常は、どれかの case が実行された段階で、switchの処ç�??、終äº?�•れますã?
189             * break="false" にすると、switchから抜けずに、継続して case との match を実行しますã?
190             * こã?場合ã?Java等と異なるã?は、直後ã?caseæ–?�Œ実行されるのではなくã?あくまで match 作業ã�?
191             * 継続されるとã�?�†ことですã?つまりã?è¤?•°の case で処ç�?‚’行いたい場合ã?、break="false" に
192             * すると同時に、match 条件もそれぞれで、ã?ãƒ?ƒ�するように設定するå¿?¦�がありますã?
193             * 初期値は、true?šブレイクする ですã?
194             *
195             * @param       flag 継続å?ç�?‚’行わなã�?�‹どã�?�‹[true:行わなã�?ブレイクする/false:継続å?ç�?‚’行う]
196             */
197            public void setIsBreak( final String flag ) {
198                    isBreak = nval( getRequestParameter( flag ),isBreak );
199            }
200    
201            /**
202             * 【TAG】switchのkeyがã?null(またã?ゼロæ–?­—å?)の場合ã?マッチするかどã�?�‹[true/false]を設定しまã�?初期値:false)ã€?
203             *
204             * @og.tag
205             * trueに設定すると、switchのkeyがã?null(またã?ゼロæ–?­—å?)の場合ã?マッチしますã?
206             * 初期値のfalse にすると、キーã�?null でなã�??合だけã?マッチå?ç�?‚’実行しますã?
207             * case の条件判定で使用されますã?
208             * 初期値はã€?false (null でなã�? ですã?
209             *
210             * @param       flag nullマッチ判定[true/false]
211             */
212            public void setIsNull( final String flag ) {
213                    isNull = nval( getRequestParameter( flag ),isNull );
214            }
215    
216            /**
217             * こã?オブジェクトã?æ–?­—å?表現を返しますã?
218             * 基本çš?�«ãƒ?ƒ�ãƒ?‚°目çš?�«使用しますã?
219             *
220             * @return こã?クラスのæ–?­—å?表現
221             */
222            @Override
223            public String toString() {
224                    return org.opengion.fukurou.util.ToString.title( this.getClass().getName() )
225                                    .println( "VERSION"                     ,VERSION        )
226                                    .println( "caseMatch"           ,caseMatch      )
227                                    .println( "isDefault"           ,isDefault      )
228                                    .println( "isBreak"                     ,isBreak        )
229                                    .println( "isNull"                      ,isNull         )
230                                    .println( "Other..."    ,getAttributes().getAttribute() )
231                                    .fixForm().toString() ;
232            }
233    }