    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)
    019import static org.opengion.fukurou.util.StringUtil.nval;
    020
    021import java.util.concurrent.atomic.AtomicInteger;       // 5.5.2.6 (2012/05/25) findbugs対応
    022
    023/**
    024 * 表示のON/OFF制御が出来るフィールドセットを作成するタグです。
    025 *
    026 * フィールドセットは関連するフォームの部品やラベルをグループ化する要素で、
    027 * 表示のON/OFF制御が出来ます。
    028 * BODY 部分にるフォーム部品などのタグを記述すれば、そのままタイトル付きのグループ化
    029 * された状態を作成できます。
    030 * useDisplayHide="false" で通常の fieldset と同じ機能になります。通常、useDisplayHide="true"
    031 * にすることで、タイトル部(一般のlegendタグ)をクリックすると、表示がON/OFFします。
    032 * useDisplayHide の初期値は、true(表示 ON/OFF機能を使用する)です。
    033 * 表示機能が使用できる状態(useDisplayHide="true")では、さらに、初期表示を行うかどうかを
    034 * 指定できます。これは、defaultNone="true" とすると初期表示は "style=display:none;" に
    035 * 設定され(つまり、表示されない状態)、defaultNone="false" とすると初期表示されます。
    036 * defaultNone の初期値は、true(表示されない状態)です。
    037 * このタグには、通常、第一要素としてBODY部に記述する legendタグ は設定不要です。
    038 * このタグの lbl 属性に、リソース情報を記述することで、直接 legendタグ を
    039 * 生成しています。
    040 *
    041 * @og.formSample
    042 * ●形式：&lt;og:fieldset
    043 *                    lbl="…"                      ラベルリソースのキー
    044 *                  [ useDisplayHide="true" ]       表示 ON/OFF機能を使用する(true)かどうか
    045 *                  [ useDisplayHide="true" ]       初期値を表示ON(false)にするかOFF(true)にするか
    046 *         &gt;
    047 *             &lt;input …" /&gt;
    048 *             &lt;input …" /&gt;
    049 *         &lt;/og:fieldset&gt;
    050 * ●body：あり(EVAL_BODY_INCLUDE:BODYをインクルードし、{&#064;XXXX} は解析しません)
    051 *
    052 * ●Tag定義：
    053 *   &lt;og:fieldset
    054 *       lbl                【TAG】ラベルリソースのラベルIDを指定します
    055 *       useDisplayHide     【TAG】表示 ON/OFF機能を使用するかどうか[true/false]を指定します(初期値:true)
    056 *       defaultNone        【TAG】表示ON/OFF機能を使用する場合の初期値を、隠し(none)にするかどうか[true/false]を指定します(初期値:true)
    057 *       caseKey            【TAG】このタグ自体を利用するかどうかの条件キーを指定します(初期値:null) 5.7.7.2 (2014/06/20)
    058 *       caseVal            【TAG】このタグ自体を利用するかどうかの条件値を指定します(初期値:null) 5.7.7.2 (2014/06/20)
    059 *       caseNN             【TAG】指定の値が、null/ゼロ文字列 でない場合(Not Null=NN)は、このタグは使用されます(初期値:判定しない) 5.7.7.2 (2014/06/20)
    060 *       caseNull           【TAG】指定の値が、null/ゼロ文字列 の場合は、このタグは使用されます(初期値:判定しない) 5.7.7.2 (2014/06/20)
    061 *       caseIf             【TAG】指定の値が、true/TRUE文字列の場合は、このタグは使用されます(初期値:判定しない)
    062 *       debug              【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false)
    063 *   &gt;   ... Body ...
    064 *   &lt;/og:fieldset&gt;
    065 *
    066 * ●使用例
    067 *    例１:通常の状態。表示ON/OFF機能を使用し、初期値は表示OFF 状態
    068 *     &lt;og:fieldset lbl="INSERT_GEA11" &gt;
    069 *         &lt;og:submit  value="insertGEA11" lbl="COPY" command="COPY" /&gt;
    070 *         &lt;og:column  name="SYSTEM_ID" useRequestValue="false" must="true" td="no" /&gt;
    071 *     &lt;/og:fieldset&gt;
    072 *
    073 *    例２:通常の状態。表示ON/OFF機能を使用し、初期値は表示ON 状態
    074 *     &lt;og:fieldset lbl="GEM0001" defaultNone="false" &gt;
    075 *         &lt;og:column  name="SYSTEM_ID" useRequestValue="false" must="true" td="no" /&gt;
    076 *     &lt;/og:fieldset&gt;
    077 *
    078 * @og.rev 4.0.0.0 (2005/11/30) 新規作成
    079 * @og.group 画面部品
    080 *
    081 * @version  4.0
    082 * @author   Kazuhiko Hasegawa
    083 * @since    JDK5.0,
    084 */
    085public class FieldsetTag extends CommonTagSupport {
    086        /** このプログラムのVERSION文字列を設定します。   {@value} */
    087        private static final String VERSION = "7.0.1.0 (2018/10/15)" ;
    088        private static final long serialVersionUID = 701020181015L ;
    089
    090        private static AtomicInteger uniqID = new AtomicInteger(1);             // 5.5.2.6 (2012/05/25) findbugs対応
    091
    092        private boolean useDisplayHide  = true;         // 表示 ON/OFF機能を使用する(true)かどうか
    093        private boolean defaultNone             = true;         // 初期値を表示ON(false)にするかOFF(true)にするか
    094
    095        /**
    096         * デフォルトコンストラクター
    097         *
    098         * @og.rev 6.4.2.0 (2016/01/29) PMD refactoring. Each class should declare at least one constructor.
    099         */
    100        public FieldsetTag() { super(); }               // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。
    101
    102        /**
    103         * Taglibの開始タグが見つかったときに処理する doStartTag() を オーバーライドします。
    104         *
    105         * @og.rev 3.8.5.2 (2006/05/31) 初期値:defaultNone を hidden で出力しておく。
    106         * @og.rev 5.5.2.6 (2012/05/25) findbugs対応。staticフィールドへの書き込みに、AtomicInteger を利用します。
    107         * @og.rev 5.7.7.2 (2014/06/20) caseKey,caseVal,caseNN,caseNull 属性を追加
    108         * @og.rev 7.0.1.0 (2018/10/15) XHTML → HTML5 対応(空要素の、"／＞" 止めを、"＞" に変更します)。
    109         *
    110         * @return      後続処理の指示( EVAL_BODY_INCLUDE )
    111         */
    112        @Override
    113        public int doStartTag() {
    114                // 5.7.7.2 (2014/06/20) caseKey,caseVal,caseNN,caseNull 属性を追加
    115                if( !useTag() ) { return SKIP_BODY ; }
    116
    117                final String id = String.valueOf( uniqID.getAndIncrement() );   // 5.5.2.6 (2012/05/25) findbugs対応
    118
    119                String hideFunc = "";
    120                String onoffMsg = "";
    121                String divBody  = "";
    122                String hiddenVal = "";
    123
    124                if( useDisplayHide ) {
    125                        hideFunc = " onClick=\"hide( \'FS" + id + "\' );\"" ;
    126                        divBody  = "<div id=\"FS" + id + "A\" style=\"display:" ;
    127//                      hiddenVal = "<input type=\"hidden\" name=\"FS" + id + "C\" value=\"" + defaultNone + "\" />" ;
    128                        hiddenVal = "<input type=\"hidden\" name=\"FS" + id + "C\" value=\"" + defaultNone + "\" >" ;           // 7.0.1.0 (2018/10/15)
    129                        if( defaultNone ) {
    130                                onoffMsg = "<span id=\"FS" + id + "B\" >+ </span>";
    131                                divBody += "none;\" >" ;
    132                        }
    133                        else {
    134                                onoffMsg = "<span id=\"FS" + id + "B\" >- </span>";
    135                                divBody += "inline;\" >" ;
    136                        }
    137                }
    138
    139                final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE )
    140                        .append( "<fieldset style=\"display:inline;\">" ).append( CR )
    141                        .append( "<legend" ).append( hideFunc ).append( '>' )           // 6.0.2.5 (2014/10/31) char を append する。
    142                        .append( "<strong>" ).append( onoffMsg )
    143                        .append( getLongLabel() )
    144                        .append( "</strong></legend>" ).append( CR )
    145                        .append( divBody )
    146                        .append( CR )
    147                        .append( hiddenVal )
    148                        .append( CR );
    149
    150                jspPrint( buf.toString() );
    151                return EVAL_BODY_INCLUDE ;      // Body インクルード( extends TagSupport 時)
    152        }
    153
    154        /**
    155         * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。
    156         *
    157         * @og.rev 5.7.7.2 (2014/06/20) caseKey,caseVal,caseNN,caseNull 属性を追加
    158         *
    159         * @return      後続処理の指示
    160         */
    161        @Override
    162        public int doEndTag() {
    163                debugPrint();           // 4.0.0 (2005/02/28)
    164
    165                // 5.7.7.2 (2014/06/20) caseKey,caseVal,caseNN,caseNull 属性を追加
    166                if( useTag() ) {
    167                        if( useDisplayHide ) {
    168                                jspPrint( "</div></fieldset>" + CR );
    169                        }
    170                        else {
    171                                jspPrint( "</fieldset>" + CR );
    172                        }
    173                }
    174
    175                return EVAL_PAGE ;              // ページの残りを評価する。
    176        }
    177
    178        /**
    179         * タグリブオブジェクトをリリースします。
    180         * キャッシュされて再利用されるので、フィールドの初期設定を行います。
    181         *
    182         */
    183        @Override
    184        protected void release2() {
    185                super.release2();
    186                useDisplayHide  = true;
    187                defaultNone             = true;
    188        }
    189
    190        /**
    191         * 【TAG】表示 ON/OFF機能を使用するかどうか[true/false]を指定します(初期値:true)。
    192         *
    193         * @og.tag
    194         * 表示 ON/OFF機能を使用する場合は、true / 通常の fieldset を使用する場合は、
    195         * false を指定します。
    196         * 初期値は、true(ON/OFF機能を使用する)です。
    197         *
    198         * @param       flag 表示ON/OFF機能 [true:使用する/false:使用しない]
    199         * @see         #setDefaultNone( String )
    200         */
    201        public void setUseDisplayHide( final String flag ) {
    202                useDisplayHide = nval( getRequestParameter( flag ),useDisplayHide ) ;
    203        }
    204
    205        /**
    206         * 【TAG】表示ON/OFF機能を使用する場合の初期値を、隠し(none)にするかどうか[true/false]を指定します(初期値:true)。
    207         *
    208         * @og.tag
    209         * 表示 ON/OFF機能を使用する場合にのみ設定値は有効に機能します。
    210         * 隠し(none)にする場合は、true を、表示にする場合は、false をセットします。
    211         * 初期値は、true(隠し(none)にする)です。
    212         *
    213         * @param       flag 初期隠し [true:隠し(none)にする/false:表示にする]
    214         * @see         #setUseDisplayHide( String )
    215         */
    216        public void setDefaultNone( final String flag ) {
    217                defaultNone = nval( getRequestParameter( flag ),defaultNone ) ;
    218        }
    219
    220        /**
    221         * このオブジェクトの文字列表現を返します。
    222         * 基本的にデバッグ目的に使用します。
    223         *
    224         * @return このクラスの文字列表現
    225         * @og.rtnNotNull
    226         */
    227        @Override
    228        public String toString() {
    229                return ToString.title( this.getClass().getName() )
    230                                .println( "VERSION"                     ,VERSION                                                )
    231                                .println( "key"                         ,getLabelInterface().getKey()   )
    232                                .println( "msglbl"                      ,getMsglbl()                                    )
    233                                .println( "useDisplayHide"      ,useDisplayHide                                 )
    234                                .println( "defaultNone"         ,defaultNone                                    )
    235                                .println( "Other..."            ,getAttributes().getAttribute() )
    236                                .fixForm().toString() ;
    237        }
    238}