    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.HybsSystemException;
    019import org.opengion.hayabusa.resource.LabelInterface;
    020import org.opengion.fukurou.util.StringUtil;
    021import org.opengion.fukurou.util.ToString;                                              // 6.1.1.0 (2015/01/17)
    022
    023import static org.opengion.fukurou.util.StringUtil.nval ;
    024
    025/**
    026 * 画面にラベルリソース等のメッセージを表示させるタグです。
    027 *
    028 * lbl 属性に ラベルリソース のキーを与えることで、 ロケールにあわせたリソースを使用して、
    029 * 画面に表示します。
    030 * 違う値をセットした場合は、 セットした値が、そのまま出力されます。これは、ロケールが
    031 * 見つからなかった場合の標準の対応方法です。
    032 * ロケールは、ユーザー情報の lang 属性を初期値で使用し、 セットされていない場合は、
    033 * リクエスト情報のロケールから取得します。
    034 * lbl 属性を使用する場合、val0 ～ val9 までの引数を使用することができます。これは、
    035 * メッセージフォーマットの、引数 {0} ～ {9} に対応して割り付けられます。
    036 *
    037 * @og.formSample
    038 * ●形式：&lt;og:message lbl="…" val0=[…] … /&gt;
    039 * ●body：あり(EVAL_BODY_BUFFERED:BODYを評価し、{&#064;XXXX} を解析します)
    040 *
    041 * ●Tag定義：
    042 *   &lt;og:message
    043 *       lbl                【TAG】ラベルリソースのラベルIDを指定します
    044 *       language           【TAG】タグ内部で使用する言語コード[ja/en/zh/…]を指定します
    045 *       command            【TAG】コマンド (INSERT,COPY,MODIFY,DELETE)をセットします
    046 *       comment            【TAG】コメントを指定します
    047 *       type               【TAG】タイプを(Label,Short,Tips,Description)から指定します(初期値:Label)
    048 *       val0               【TAG】メッセージの引数{0}を指定します
    049 *       val1               【TAG】メッセージの引数{1}を指定します
    050 *       val2               【TAG】メッセージの引数{2}を指定します
    051 *       val3               【TAG】メッセージの引数{3}を指定します
    052 *       val4               【TAG】メッセージの引数{4}を指定します
    053 *       val5               【TAG】メッセージの引数{5}を指定します
    054 *       val6               【TAG】メッセージの引数{6}を指定します
    055 *       val7               【TAG】メッセージの引数{7}を指定します
    056 *       val8               【TAG】メッセージの引数{8}を指定します
    057 *       val9               【TAG】メッセージの引数{9}を指定します
    058 *       caseKey            【TAG】このタグ自体を利用するかどうかの条件キーを指定します(初期値:null)
    059 *       caseVal            【TAG】このタグ自体を利用するかどうかの条件値を指定します(初期値:null)
    060 *       caseNN             【TAG】指定の値が、null/ゼロ文字列 でない場合(Not Null=NN)は、このタグは使用されます(初期値:判定しない)
    061 *       caseNull           【TAG】指定の値が、null/ゼロ文字列 の場合は、このタグは使用されます(初期値:判定しない)
    062 *       caseIf             【TAG】指定の値が、true/TRUE文字列の場合は、このタグは使用されます(初期値:判定しない)
    063 *       debug              【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false)
    064 *   &gt;   ... Body ...
    065 *   &lt;/og:message&gt;
    066 *
    067 * ●使用例
    068 *     &lt;og:message lbl=&quot;MSG0032&quot; language=&quot;ja&quot; /&gt;
    069 *
    070 *        lbl       : MessageResource.properties のキー
    071 *        language  : ロケール(オプション)
    072 *
    073 *     例１)
    074 *         &lt;og:message lbl=&quot;MSG0032&quot; &gt;検索条件&lt;/og:message&gt;
    075 *
    076 *        BODY 部分は、無視されます。コメント等に使用できます。
    077 *        HTMLファイルには、コメント部分は出力されません。
    078 *
    079 *        typeをTipsにした場合には出力をclass=ogmsgのspanタグで囲います。   5.9.22.2 (2017/07/21)
    080 *
    081 * @og.group 画面部品
    082 *
    083 * @version  4.0
    084 * @author   Kazuhiko Hasegawa
    085 * @since    JDK5.0,
    086 */
    087public class MessageTag extends CommonTagSupport {
    088        /** このプログラムのVERSION文字列を設定します。   {@value} */
    089        private static final String VERSION = "7.1.0.1 (2020/02/07)" ;
    090        private static final long serialVersionUID = 710120200207L ;
    091
    092        private String          comment ;
    093        private String[]        values  ;
    094        // 4.0.0 (2005/01/31) メッセージの種類を指定できるようにします。
    095        private String          type    = "Label" ;     // Label,Short,Tips,Description が指定できます。
    096        private String          cmdMsg  ;
    097
    098        private static final String[] TYPE_LIST = { "Label","Short","Tips","Description" };
    099
    100        // 6.8.5.0 (2018/01/09) PMD Variables that are final and static should be all capitals。tipsPre,tipsSuf → TIPS_PRE,TIPS_SUF
    101        private static final String TIPS_PRE = "<span class=\"ogmsg\">"; // 5.9.22.2 (2017/07/21)
    102        private static final String TIPS_SUF = "</span>";
    103
    104        /**
    105         * デフォルトコンストラクター
    106         *
    107         * @og.rev 6.4.2.0 (2016/01/29) PMD refactoring. Each class should declare at least one constructor.
    108         */
    109        public MessageTag() { super(); }                // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。
    110
    111        /**
    112         * Taglibの開始タグが見つかったときに処理する doStartTag() を オーバーライドします。
    113         *
    114         * @og.rev 5.2.2.0 (2010/11/01) caseKey 、caseVal 属性対応
    115         *
    116         * @return      後続処理の指示( EVAL_BODY_BUFFERED )
    117         */
    118        @Override
    119        public int doStartTag() {
    120                // 5.2.2.0 (2010/11/01) caseKey 、caseVal 属性対応
    121                // 6.4.1.1 (2016/01/16) PMD refactoring. A method should have only one exit point, and that should be the last statement in the method
    122                return useTag()
    123                                        ? EVAL_BODY_BUFFERED            // Body を評価する。( extends BodyTagSupport 時)
    124                                        : SKIP_BODY ;                           // Body を評価しない
    125        }
    126
    127        /**
    128         * Taglibのタグ本体を処理する doAfterBody() を オーバーライドします。
    129         *
    130         * @og.rev 3.1.1.0 (2003/03/28) ボディの内容を取得する処理を、CommonTagSupport で行う。
    131         *
    132         * @return      後続処理の指示(SKIP_BODY)
    133         */
    134        @Override
    135        public int doAfterBody() {
    136                final String str = getBodyString();
    137
    138                if( str != null && str.length() > 0 ) {
    139                        comment = StringUtil.htmlFilter( str );
    140                }
    141
    142                return SKIP_BODY ;
    143        }
    144
    145        /**
    146         * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。
    147         *
    148         * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。release2() を doEndTag()で呼ぶ。
    149         * @og.rev 5.2.2.0 (2010/11/01) caseKey 、caseVal 属性対応
    150         *
    151         * @return      後続処理の指示
    152         */
    153        @Override
    154        public int doEndTag() {
    155                debugPrint();           // 4.0.0 (2005/02/28)
    156                // 5.2.2.0 (2010/11/01) caseKey 、caseVal 属性対応
    157                if( useTag() ) {
    158                        jspPrint( makeTag() );
    159                }
    160                return EVAL_PAGE ;
    161        }
    162
    163        /**
    164         * タグリブオブジェクトをリリースします。
    165         * キャッシュされて再利用されるので、フィールドの初期設定を行います。
    166         *
    167         * @og.rev 2.0.0.4 (2002/09/27) カスタムタグの release() メソッドを、追加
    168         * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。release2() を doEndTag()で呼ぶ。
    169         *
    170         */
    171        @Override
    172        protected void release2() {
    173                super.release2();
    174                comment = null;
    175                values  = null;
    176                type    = "Label" ;     // Label,Short,Tips,Description が指定できます。
    177                cmdMsg  = null;
    178        }
    179
    180        /**
    181         * 表示用の文字列を指定します。
    182         *
    183         * @og.rev 4.0.0.0 (2005/01/31) タイプ別メッセージ情報を返します。
    184         * @og.rev 4.0.0.0 (2007/10/18) メッセージリソース統合( getResource().getMessage ⇒ getResource().getLabel )
    185         * @og.ref 5.9.22.2 (2017/07/21) Tipsの場合のみ、前後をclass=ogmsg付きのspanで囲います。
    186         * @og.rev 6.8.5.0 (2018/01/09) PMD Variables that are final and static should be all capitals。tipsPre,tipsSuf → TIPS_PRE,TIPS_SUF
    187         * @og.rev 7.1.0.1 (2020/02/07) ショートラベルと概要に引数を渡します。
    188         *
    189         * @return  変換後の文字列
    190         */
    191        private String makeTag() {
    192                String val  = null;
    193
    194                final LabelInterface label = getLabelInterface();
    195
    196                final char ch = type.charAt(0); // Label,Short,Tips,Description
    197                // 6.4.1.1 (2016/01/16) PMD refactoring. Avoid if (x != y) ..; else ..;
    198                if( label == null ) {
    199                        val = cmdMsg == null ? comment : getResource().getLabel( cmdMsg );      // cmdMsg = INSERT,COPY,MODIFY,DELETE,null
    200                }
    201                else {
    202                        switch( ch ) {
    203                                case 'L': val = label.getMessage( values );                     break;
    204//                              case 'S': val = label.getShortLabel();                          break;
    205                                case 'S': val = label.getShortMessage( values );        break;                  // 7.1.0.1 (2020/02/07)
    206                                case 'T': val = TIPS_PRE + label.getLongLabel() + TIPS_SUF; break;      // 6.8.5.0 (2018/01/09)
    207//                              case 'D': val = label.getDescription();         break;
    208                                case 'D': val = label.getDescription( values);          break;                  // 7.1.0.1 (2020/02/07)
    209                                default :                                                                                       break;
    210                        }
    211                }
    212
    213                return val;
    214        }
    215
    216        /**
    217         * 【TAG】コメントを指定します。
    218         *
    219         * @og.tag
    220         * msg 属性でメッセージリソースから読み取りますが,開発途中で
    221         * リソース登録を済ましていない状態でコメントを入れる場合に、
    222         * 直接コメントをかけるようにします。
    223         *
    224         * @og.rev 2.2.0.0 (2002/12/17) 中国語(国際化)対応 エンコードの取得方法変更
    225         * @og.rev 3.0.0.0 (2002/12/25) StringUtil#changeString 廃止
    226         *
    227         * @param   cmnt コメント文字列
    228         */
    229        public void setComment( final String cmnt ) {
    230                comment = cmnt;
    231        }
    232
    233        /**
    234         * 【TAG】タイプ[Label/Short/Tips/Description]を指定します(初期値:Label)。
    235         *
    236         * @og.tag
    237         * タイプは、ラベル／メッセージリソースのどの情報を取得したいかを指定できます。
    238         * 従来のラベル／メッセージは、Label に相当します。
    239         * なお、指定は、それぞれの頭文字('L','S','T','D')のみでも可能です。
    240         * 初期値は、"Label" です。
    241         * ・Label  : ラベル／メッセージ表示
    242         * ・Short  : 表形式で使用する短いラベル表示
    243         * ・Tips   : ラベルの上にTips表示
    244         * ・Description : 概要説明を表示
    245         *
    246         * @og.rev 4.0.0.0 (2005/01/31) 新規登録
    247         *
    248         * @param   tp タイプ文字列 [Label/Short/Tips/Description]
    249         */
    250        public void setType( final String tp ) {
    251                type = nval( getRequestParameter( tp ),type );
    252
    253                final char ch = type.charAt(0); // Label,Short,Tips,Description
    254
    255                if( "LSTD".indexOf( ch ) < 0 ) {
    256                        final String errMsg = "type に、指定不可能な文字が設定されました。type=[" + type
    257                                        + "] TYPE_LIST=[" + StringUtil.array2csv( TYPE_LIST ) + "]";
    258                        throw new HybsSystemException( errMsg );
    259                }
    260        }
    261
    262        /**
    263         * 【TAG】メッセージの引数{0}を指定します。
    264         *
    265         * @og.tag メッセージの引数を指定します。
    266         *
    267         * @param   value メッセージの引数
    268         */
    269        public void setVal0( final String value ) { setValues( 0, value ); }
    270
    271        /**
    272         * 【TAG】メッセージの引数{1}を指定します。
    273         *
    274         * @og.tag メッセージの引数を指定します。
    275         *
    276         * @param   value メッセージの引数
    277         */
    278        public void setVal1( final String value ) { setValues( 1, value ); }
    279
    280        /**
    281         * 【TAG】メッセージの引数{2}を指定します。
    282         *
    283         * @og.tag メッセージの引数を指定します。
    284         *
    285         * @param   value メッセージの引数
    286         */
    287        public void setVal2( final String value ) { setValues( 2, value ); }
    288
    289        /**
    290         * 【TAG】メッセージの引数{3}を指定します。
    291         *
    292         * @og.tag メッセージの引数を指定します。
    293         *
    294         * @param   value メッセージの引数
    295         */
    296        public void setVal3( final String value ) { setValues( 3, value ); }
    297
    298        /**
    299         * 【TAG】メッセージの引数{4}を指定します。
    300         *
    301         * @og.tag メッセージの引数を指定します。
    302         *
    303         * @param   value メッセージの引数
    304         */
    305        public void setVal4( final String value ) { setValues( 4, value ); }
    306
    307        /**
    308         * 【TAG】メッセージの引数{5}を指定します。
    309         *
    310         * @og.tag メッセージの引数を指定します。
    311         *
    312         * @param   value メッセージの引数
    313         */
    314        public void setVal5( final String value ) { setValues( 5, value ); }
    315
    316        /**
    317         * 【TAG】メッセージの引数{6}を指定します。
    318         *
    319         * @og.tag メッセージの引数を指定します。
    320         *
    321         * @param   value メッセージの引数
    322         */
    323        public void setVal6( final String value ) { setValues( 6, value ); }
    324
    325        /**
    326         * 【TAG】メッセージの引数{7}を指定します。
    327         *
    328         * @og.tag メッセージの引数を指定します。
    329         *
    330         * @param   value メッセージの引数
    331         */
    332        public void setVal7( final String value ) { setValues( 7, value ); }
    333
    334        /**
    335         * 【TAG】メッセージの引数{8}を指定します。
    336         *
    337         * @og.tag メッセージの引数を指定します。
    338         *
    339         * @param   value メッセージの引数
    340         */
    341        public void setVal8( final String value ) { setValues( 8, value ); }
    342
    343        /**
    344         * 【TAG】メッセージの引数{9}を指定します。
    345         *
    346         * @og.tag メッセージの引数{9}を指定します。
    347         *
    348         * @param   value メッセージの引数
    349         */
    350        public void setVal9( final String value ) { setValues( 9, value ); }
    351
    352        /**
    353         * メッセージの引数を指定します。
    354         *
    355         * @param   no    メッセージの引数の配列番号
    356         * @param   value メッセージの引数
    357         */
    358        private void setValues( final int no,final String val ) {
    359                if( values == null ) { values = new String[10]; }
    360                values[no] = getRequestParameter( val );
    361        }
    362
    363        /**
    364         * 【TAG】コマンド (INSERT,COPY,MODIFY,DELETE)をセットします。
    365         *
    366         * @og.tag
    367         * コマンドは,HTMLから(get/post)指定されますので,CMD_xxx で設定される
    368         * フィールド定数値のいづれかを、指定できます。
    369         * コマンド (INSERT,COPY,MODIFY,DELETE)に対応したメッセージを表示します。
    370         * INSERT : MSG0044  追加処理を行います。
    371         * COPY   : MSG0045  複写処理を行います。
    372         * MODIFY : MSG0046  変更処理を行います。
    373         * DELETE : MSG0047  削除処理を行います。
    374         *
    375         * なお、command によるメッセージの自動選択は、lbl ともにセットされていない
    376         * 場合にのみ有効になります。
    377         *
    378         * @og.rev 4.0.0.0 (2006/11/31) 新規登録
    379         *
    380         * @param       cmd コマンド (public static final 宣言されている文字列)
    381         */
    382        public void setCommand( final String cmd ) {
    383                final String cmd2 = nval( getRequestParameter( cmd ),null );
    384                if(      "INSERT".equalsIgnoreCase( cmd2 ) ) { cmdMsg = "MSG0044"; }
    385                else if( "COPY".equalsIgnoreCase(   cmd2 ) ) { cmdMsg = "MSG0045"; }
    386                else if( "MODIFY".equalsIgnoreCase( cmd2 ) ) { cmdMsg = "MSG0046"; }
    387                else if( "DELETE".equalsIgnoreCase( cmd2 ) ) { cmdMsg = "MSG0047"; }
    388                else { cmdMsg = null; }
    389        }
    390
    391        /**
    392         * このオブジェクトの文字列表現を返します。
    393         * 基本的にデバッグ目的に使用します。
    394         *
    395         * @return このクラスの文字列表現
    396         * @og.rtnNotNull
    397         */
    398        @Override
    399        public String toString() {
    400                return ToString.title( this.getClass().getName() )
    401                                .println( "VERSION"             ,VERSION        )
    402                                .println( "comment"             ,comment        )
    403                                .println( "values"              ,values         )
    404                                .println( "type"                ,type           )
    405                                .println( "TYPE_LIST"   ,TYPE_LIST      )
    406                                .println( "Other..."    ,getAttributes().getAttribute() )
    407                                .fixForm().toString() ;
    408        }
    409}