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 java.util.concurrent.ConcurrentMap;
019import java.util.concurrent.ConcurrentHashMap;
020
021import org.opengion.hayabusa.common.HybsSystemException;
022import org.opengion.fukurou.util.ToString;
023
024/**
025 * ValueMapTag にパラメーターを渡す為のタグクラスです。
026 *
027 * valueMap タグでは、特殊な 処理を行っており、そのMapで未使用のキーワードを
028 * 出力するために、このタグを使用します。
029 * valueMapParam の BODY部の文字列を、繰り返して、valueMap タグの未使用キーに適用します。
030 * キーワードは、{@XXXX} 固定で、XXXX 部分を、valueMap の未使用キーに変換します。
031 *
032 * このタグは、ValueMapTag の内部からしか、使用できません。
033 *
034 * @og.formSample
035 * ●形式:
036 *     <og:valueMapParam clsKey="CLASS_KEY" >
037 *          <tr><td class="LBL">{@$XXXX 1}</td><td>{@$XXXX 2}</td><td>{@$XXXX 3}</td></tr>
038 *     </og:valueMapParam
039 *
040 * ●body:あり(EVAL_BODY_BUFFERED:BODYを評価し、{@XXXX} を解析します)
041 *
042 * ●Tag定義:
043 *   <og:valueMapParam
044 *       noneClassKey       【TAG】繰返し対象が無い場合に、display:none; を出力する class 属性名(初期値:null)
045 *       restMarkClm        【TAG】繰返し対象が無い場合に、DBTableModelにマークするカラム名(初期値:null)
046 *       restMarkVal        【TAG】繰返し対象が無い場合に、DBTableModelにマークする値(初期値:null)
047 *       caseKey            【TAG】このタグ自体を利用するかどうかの条件キーを指定します(初期値:null)
048 *       caseVal            【TAG】このタグ自体を利用するかどうかの条件値を指定します(初期値:null)
049 *       caseNN             【TAG】指定の値が、null/ゼロ文字列 でない場合(Not Null=NN)は、このタグは使用されます(初期値:判定しない)
050 *       caseNull           【TAG】指定の値が、null/ゼロ文字列 の場合は、このタグは使用されます(初期値:判定しない)
051 *       caseIf             【TAG】指定の値が、true/TRUE文字列の場合は、このタグは使用されます(初期値:判定しない)
052 *       debug              【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false)
053 *   >   ... Body ...
054 *   </og:valueMapParam>
055 *
056 * ●使用例
057 *     <og:valueMap ・・・・・ >
058 *          ・・・・・ 
059 *         <og:valueMapParam
060 *               ・・・・・ 
061 *         </og:valueMapParam
062 *     </og:valueMap
063 *
064 * @og.rev 6.7.8.0 (2017/04/21) 新規作成
065 * @og.group ファイル出力
066 *
067 * @version  6.7
068 * @author   Kazuhiko Hasegawa
069 * @since    JDK8.0,
070 */
071public class ValueMapParamTag extends CommonTagSupport {
072        /** このプログラムのVERSION文字列を設定します。   {@value} */
073        private static final String VERSION = "6.7.8.0 (2017/04/21)" ;
074        private static final long serialVersionUID = 678020170421L ;
075
076        /** ValueMapParamTag クラスのキーワードの enum */
077        public static enum VMP_KEYS {
078                NONE_CLS_KEY    ,                               // noneClassKey のキーワード
079                REST_MARK_CLM   ,                               // restMarkClm のキーワード
080                REST_MARK_VAL   ,                               // restMarkVal のキーワード
081                REST_CHANGE_KEY ,                               // ValueMapParamTag の文字列を置き換えるタグ名
082                BODY_VAL                ;                               // このタグのBODY部の文字列(未変換)
083        };
084
085        // 各種設定情報を、管理するMapオブジェクト。これを、上位の ValueMapTag に渡す。
086        private final ConcurrentMap<VMP_KEYS,String> paramMap = new ConcurrentHashMap<>();
087
088        private static final String REST_CHANGE_VAL = "h_REST_CHANGE_VAL" ;
089
090        /**
091         * デフォルトコンストラクター
092         *
093         */
094        public ValueMapParamTag() { super(); }          // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。
095
096        /**
097         * Taglibの開始タグが見つかったときに処理する doStartTag() を オーバーライドします。
098         *
099         * @return      後続処理の指示
100         */
101        @Override
102        public int doStartTag() {
103                return useTag() 
104                                        ? EVAL_BODY_BUFFERED            // Body を評価する。( extends BodyTagSupport 時)
105                                        : SKIP_BODY;                            // Body を評価しない
106        }
107
108        /**
109         * Taglibのタグ本体を処理する doAfterBody() を オーバーライドします。
110         *
111         * @return      後続処理の指示(SKIP_BODY)
112         */
113        @Override
114        public int doAfterBody() {
115                putMap( VMP_KEYS.BODY_VAL , getBodyRawString() );               // {&#064;XXXX}を変換しない生のBODY文を設定します
116
117                return SKIP_BODY ;
118        }
119
120        /**
121         * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。
122         *
123         * @return      後続処理の指示
124         */
125        @Override
126        public int doEndTag() {
127                debugPrint();
128
129                if( useTag() ) {
130                        final ValueMapTag vm_Tag = (ValueMapTag)findAncestorWithClass( this,ValueMapTag.class );
131                        if( vm_Tag == null ) {
132                                final String errMsg = "<b>" + getTagName() + "タグは、ValueMapTagの内側(要素)に記述してください。</b>";
133                                throw new HybsSystemException( errMsg );
134                        }
135
136                        jspPrint( "{@" + REST_CHANGE_VAL + "}" );                               // ValueMapParamTag を置き換えます。
137                        putMap( VMP_KEYS.REST_CHANGE_KEY , REST_CHANGE_VAL );   // Map に入れて、ValueMapTag に渡します。
138
139                        vm_Tag.setParam( paramMap );
140                }
141                return EVAL_PAGE ;
142        }
143
144        /**
145         * タグリブオブジェクトをリリースします。
146         * キャッシュされて再利用されるので、フィールドの初期設定を行います。
147         *
148         */
149        @Override
150        protected void release2() {
151                super.release2();
152                paramMap.clear() ;
153        }
154
155        /**
156         * 内部の paramMap に、登録します。
157         *
158         * ConcurrentMap は、nullのキーも値も設定できないので、val のnull判定処理が
159         * 必要ですが、各Map登録時に行うのではなく、ここに集約します。
160         * val がnull か、空文字列の場合は、Map にセットしません。
161         *
162         * @param   key paramMap に、登録するVMP_KEYS enum のキー
163         * @param   val paramMap に、登録する値。
164         */
165        private void putMap( final VMP_KEYS key , final String val ) {
166                if( val != null && !val.isEmpty() ) {
167                        paramMap.put( key,val );
168                }
169        }
170
171        /**
172         * 【TAG】繰返し対象が無い場合に、display:none; を出力する class 名を指定します(初期値:null)。
173         *
174         * @og.tag
175         * valueMap タグで、繰返し処理が無い場合に、このclassキーに対して、display:none; を出力します。
176         * null (未指定) の場合は、display:none; を出力しません。
177         *
178         * @param   clsKey display:none; を出力する class 名
179         */
180        public void setNoneClassKey( final String clsKey ) {
181                putMap( VMP_KEYS.NONE_CLS_KEY , getRequestParameter( clsKey ) );
182        }
183
184        /**
185         * 【TAG】繰返し対象が無い場合に、DBTableModelにマークするカラム名(初期値:null)。
186         *
187         * @og.tag
188         * valueMap タグで、繰返し処理が無い場合に、DBTableModel の指定のカラムに、
189         * マーク(値の設定)を行うカラムIDを指定します。
190         * 例えば、クラス属性に指定しているカラムの値を書き換えれば、対象無しとして
191         * 追加されたデータに、色づけなどを行うことが出来ます。
192         *
193         * @param   clm DBTableModelにマークするカラム名
194         */
195        public void setRestMarkClm( final String clm ) {
196                putMap( VMP_KEYS.REST_MARK_CLM , getRequestParameter( clm ) );
197        }
198
199        /**
200         * 【TAG】繰返し対象が無い場合に、DBTableModelにマークする値(初期値:null)。
201         *
202         * @og.tag
203         * valueMap タグで、繰返し処理が無い場合に、DBTableModel の指定のカラムに、
204         * マーク(値の設定)を行うカラムIDに指定する値を指定します。
205         * 例えば、クラス属性に指定しているカラムの値を書き換えれば、対象無しとして
206         * 追加されたデータに、色づけなどを行うことが出来ます。
207         *
208         * @param   val DBTableModelにマークする値
209         */
210        public void setRestMarkVal( final String val ) {
211                putMap( VMP_KEYS.REST_MARK_VAL , getRequestParameter( val ) );
212        }
213
214        /**
215         * このオブジェクトの文字列表現を返します。
216         * 基本的にデバッグ目的に使用します。
217         *
218         * @return このクラスの文字列表現
219         * @og.rtnNotNull
220         */
221        @Override
222        public String toString() {
223                final ToString toStr = ToString.title( this.getClass().getName() );
224
225                paramMap.forEach( (k,v) -> toStr.println( k.name() , v ) );
226
227                return toStr.fixForm().toString() ;
228
229        //      return ToString.title( this.getClass().getName() )
230        //                      .println( "VERSION"             ,VERSION        )
231        //                      .println( "clsKey"              ,clsKey         )
232        //                      .println( "value"               ,value          )
233        //                      .println( "Other..."    ,getAttributes().getAttribute() )
234        //                      .fixForm().toString() ;
235        }
236}