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