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 enum VMP_KEYS {
085//      public static enum VMP_KEYS {
086                /** noneClassKey のキーワード */                                      NONE_CLS_KEY    ,
087                /** restMarkClm のキーワード */                     REST_MARK_CLM     ,
088                /** restMarkVal のキーワード */                     REST_MARK_VAL     ,
089                /** ValueMapParamTag の文字列を置き換えるタグ名 */  REST_CHANGE_KEY  ,
090                /** YYYYキーワードに置換するグループカラム名 */              GRP_KEY_CLM               ,
091                /** このタグのBODY部の文字列(未変換) */             BODY_VAL         ;
092        };
093
094        // 各種設定情報を、管理するMapオブジェクト。これを、上位の ValueMapTag に渡す。
095        private final ConcurrentMap<VMP_KEYS,String> paramMap = new ConcurrentHashMap<>();
096
097        private static final String REST_CHANGE_VAL = "h_REST_CHANGE_VAL" ;
098
099        /**
100         * デフォルトコンストラクター
101         *
102         */
103        public ValueMapParamTag() { super(); }          // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。
104
105        /**
106         * Taglibの開始タグが見つかったときに処理する doStartTag() を オーバーライドします。
107         *
108         * @return      後続処理の指示
109         */
110        @Override
111        public int doStartTag() {
112                return useTag()
113                                        ? EVAL_BODY_BUFFERED            // Body を評価する。( extends BodyTagSupport 時)
114                                        : SKIP_BODY;                            // Body を評価しない
115        }
116
117        /**
118         * Taglibのタグ本体を処理する doAfterBody() を オーバーライドします。
119         *
120         * @return      後続処理の指示(SKIP_BODY)
121         */
122        @Override
123        public int doAfterBody() {
124                putMap( VMP_KEYS.BODY_VAL , getBodyRawString() );               // {&#064;XXXX}を変換しない生のBODY文を設定します
125
126                return SKIP_BODY ;
127        }
128
129        /**
130         * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。
131         *
132         * @return      後続処理の指示
133         */
134        @Override
135        public int doEndTag() {
136                debugPrint();
137
138                if( useTag() ) {
139                        final ValueMapTag vm_Tag = (ValueMapTag)findAncestorWithClass( this,ValueMapTag.class );
140                        if( vm_Tag == null ) {
141                                final String errMsg = "<b>" + getTagName() + "タグは、ValueMapTagの内側(要素)に記述してください。</b>";
142                                throw new HybsSystemException( errMsg );
143                        }
144
145                        jspPrint( "{@" + REST_CHANGE_VAL + "}" );                               // ValueMapParamTag を置き換えます。
146                        putMap( VMP_KEYS.REST_CHANGE_KEY , REST_CHANGE_VAL );   // Map に入れて、ValueMapTag に渡します。
147
148                        vm_Tag.setParam( paramMap );
149                }
150                return EVAL_PAGE ;
151        }
152
153        /**
154         * タグリブオブジェクトをリリースします。
155         * キャッシュされて再利用されるので、フィールドの初期設定を行います。
156         *
157         */
158        @Override
159        protected void release2() {
160                super.release2();
161                paramMap.clear() ;
162        }
163
164        /**
165         * 内部の paramMap に、登録します。
166         *
167         * ConcurrentMap は、nullのキーも値も設定できないので、val のnull判定処理が
168         * 必要ですが、各Map登録時に行うのではなく、ここに集約します。
169         * val がnull か、空文字列の場合は、Map にセットしません。
170         *
171         * @param   key paramMap に、登録するVMP_KEYS enum のキー
172         * @param   val paramMap に、登録する値。
173         */
174        private void putMap( final VMP_KEYS key , final String val ) {
175                if( val != null && !val.isEmpty() ) {
176                        paramMap.put( key,val );
177                }
178        }
179
180        /**
181         * 【TAG】繰返し対象が無い場合に、display:none; を出力する class 名を指定します(初期値:null)。
182         *
183         * @og.tag
184         * valueMap タグで、繰返し処理が無い場合に、このclassキーに対して、display:none; を出力します。
185         * null (未指定) の場合は、display:none; を出力しません。
186         *
187         * @param   clsKey display:none; を出力する class 名
188         */
189        public void setNoneClassKey( final String clsKey ) {
190                putMap( VMP_KEYS.NONE_CLS_KEY , getRequestParameter( clsKey ) );
191        }
192
193        /**
194         * 【TAG】繰返し対象が無い場合に、DBTableModelにマークするカラム名(初期値:null)。
195         *
196         * @og.tag
197         * valueMap タグで、繰返し処理が無い場合に、DBTableModel の指定のカラムに、
198         * マーク(値の設定)を行うカラムIDを指定します。
199         * 例えば、クラス属性に指定しているカラムの値を書き換えれば、対象無しとして
200         * 追加されたデータに、色づけなどを行うことが出来ます。
201         *
202         * @param   clm DBTableModelにマークするカラム名
203         */
204        public void setRestMarkClm( final String clm ) {
205                putMap( VMP_KEYS.REST_MARK_CLM , getRequestParameter( clm ) );
206        }
207
208        /**
209         * 【TAG】繰返し対象が無い場合に、DBTableModelにマークする値(初期値:null)。
210         *
211         * @og.tag
212         * valueMap タグで、繰返し処理が無い場合に、DBTableModel の指定のカラムに、
213         * マーク(値の設定)を行うカラムIDに指定する値を指定します。
214         * 例えば、クラス属性に指定しているカラムの値を書き換えれば、対象無しとして
215         * 追加されたデータに、色づけなどを行うことが出来ます。
216         *
217         * @param   val DBTableModelにマークする値
218         */
219        public void setRestMarkVal( final String val ) {
220                putMap( VMP_KEYS.REST_MARK_VAL , getRequestParameter( val ) );
221        }
222
223        /**
224         * 【TAG】繰返し対象が無い場合に、YYYYキーワードに置換するグループカラム名を指定します(初期値:null)。
225         *
226         * @og.tag
227         * valueMap タグで、繰返し処理が無い場合に、DBTableModel の指定のカラムを
228         * 利用して、YYYYキーワードと置換します。
229         * これは、グループキーワードが同一のカラムを、横持ちに順番に表示させる場合に、有効です。
230         * 初期値は、未設定なので、YYYYキーワードは、置換されずに、そのまま残ります。
231         *
232         * @og.rev 6.9.9.0 (2018/08/20) YYYYキーワードに置換するグループカラム名
233         *
234         * @param   clm YYYYキーワードに置換するグループカラム名
235         */
236        public void setGrpKeyClm( final String clm ) {
237                putMap( VMP_KEYS.GRP_KEY_CLM , getRequestParameter( clm ) );
238        }
239
240        /**
241         * このオブジェクトの文字列表現を返します。
242         * 基本的にデバッグ目的に使用します。
243         *
244         * @return このクラスの文字列表現
245         * @og.rtnNotNull
246         */
247        @Override
248        public String toString() {
249                final ToString toStr = ToString.title( this.getClass().getName() );
250
251                paramMap.forEach( (k,v) -> toStr.println( k.name() , v ) );
252
253                return toStr.fixForm().toString() ;
254
255        //      return ToString.title( this.getClass().getName() )
256        //                      .println( "VERSION"             ,VERSION        )
257        //                      .println( "clsKey"              ,clsKey         )
258        //                      .println( "value"               ,value          )
259        //                      .println( "Other..."    ,getAttributes().getAttribute() )
260        //                      .fixForm().toString() ;
261        }
262}