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.fukurou.util.Attributes;
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 * 検索結果の DBTableModelオブジェクトのカラム値を操作(設定、変換、ADDなど)するタグです。
027 *
028 * entry タグの子タグとして使用します。entryタグと、このcolumnSetタグの command
029 * が同じ場合のみ、実行されます。
030 * 処理方法は、action で指定します。
031 *
032 * @og.formSample
033 * ●形式:<og:entry command="…">
034 *             <og:setColumn
035 *                 command   ="…"          : entryタグのcommandと一致する場合に実行
036 *                 columnId  ="…"          : 処理を行うカラムIDを指定(必須,複数指定可)
037 *                 action    ="…"          : 処理方法を指定
038 *                 value     ="…"          : 設定する値を指定(action="TBLSET"のみ[カラム名]使用可能)
039 *                 conditionKey  ="…"      : 条件判定するカラムIDを指定(初期値は columnId )
040 *                 conditionList ="…"      : 条件判定する値のリストを、"|"で区切って登録(初期値は、無条件)
041 *             />
042 *         </og:entry>
043 * ●body:なし
044 *
045 * ●Tag定義:
046 *   <og:columnSet
047 *       command            【TAG】コマンド (INSERT/COPY/MODIFY/DELETE/ENTRY/CHANGE/RESET/ALLRESET/ALLACTION/RESETDATA/INSERTONE/REALDELETE/REQENTRY)を設定します
048 *       columnId         ○【TAG】カラムIDをセットします(複数指定時は、CSV形式で設定する)(必須)。
049 *       value              【TAG】値をセットします
050 *       action             【TAG】アクション(DEFAULT/CLEAR/ADD/SET/NULLSET/LOWER/UPPER/COPY/TBLSET/TBLNULLSET/WRTCTRL/DBMENU/REQSET/SEQSET)をセットします
051 *       conditionKey       【TAG】条件判定するカラムIDを指定します(初期値は columnId )
052 *       conditionList      【TAG】条件判定する値のリストを、"|"で区切って登録します(初期値:無条件)
053 *       caseKey            【TAG】このタグ自体を利用するかどうかの条件キーを指定します(初期値:null) 5.7.7.2 (2014/06/20)
054 *       caseVal            【TAG】このタグ自体を利用するかどうかの条件値を指定します(初期値:null) 5.7.7.2 (2014/06/20)
055 *       caseNN             【TAG】指定の値が、null/ゼロ文字列 でない場合(Not Null=NN)は、このタグは使用されます(初期値:判定しない) 5.7.7.2 (2014/06/20)
056 *       caseNull           【TAG】指定の値が、null/ゼロ文字列 の場合は、このタグは使用されます(初期値:判定しない) 5.7.7.2 (2014/06/20)
057 *       caseIf             【TAG】指定の値が、true/TRUE文字列の場合は、このタグは使用されます(初期値:判定しない)
058 *       debug              【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false)
059 *   />
060 *
061 * ●使用例
062 *    <og:entry command="{@command}"  >
063 *        <og:columnSet command="{@command}" columnId="ECNO"   action="CLEAR" />
064 *        <og:columnSet command="{@command}" columnId="JYOKYO" action="SET" value="1" />
065 *    </og:entry>
066 *
067 *    <og:entry command="MODIFY" rows="1" >
068 *        <og:columnSet command="MODIFY" columnId="key" action="TBLSET" value ="[key][lang]"/>
069 *    </og:entry>
070 *
071 *    command属性 は、entryタグのcommand属性と同一の場合のみ、処理します。
072 *    [command属性]
073 *      INSERT     新規
074 *      COPY       複写
075 *      MODIFY     変更
076 *      DELETE     削除
077 *      ENTRY      エントリー
078 *      CHANGE     チェンジ
079 *      RESET      リセット
080 *      ALLRESET   全件リセット
081 *      ALLACTION  オールアクション
082 *      RESETDATA  リセットデータ
083 *      INSERTONE  新規(1行のみ)
084 *      REALDELETE 物理削除
085 *      REQENTRY   リクエスト変数設定
086 *
087 *    [action属性]
088 *      DEFAULT カラムリソースで定義した初期値をセットします。
089 *      CLEAR   値をクリア(ゼロストリング "" )します。
090 *      ADD     現在の値を +1 します。  0 ⇒ 1 , A ⇒ B , 9 ⇒ 10。value属性と併用すれば、指定の値を加算できます。
091 *      SET     value で設定した値を 新しい値として登録します。
092 *      NULLSET 元の値が NULL の場合だけ、value で設定した新しい値を登録します。
093 *      LOWER   小文字に変換します。
094 *      UPPER   大文字に変換します。
095 *      COPY    value にコピー元のカラムIDをセットすれば、その値を代入します。
096 *      TBLSET  DBTableModel の内容を取り込んで指定の columnId カラムに設定します。
097 *              [カラム名] で指定できます。
098 *              また、これは文字列を解析して、 value を作成しますので,文字列連結等に使用できます。
099 *      TBLNULLSET 元の値が NULL の場合だけ、TBLSETを実行します。         6.9.9.0 (2018/08/20) 追加
100 *      WRTCTRL writableControl を使用したカラムデータの先頭アンダーバーを削除します。
101 *      DBMENU  DBMENUでパラメータ設定(コロン連結文字)を使用したカラムデータの先頭データのみにします。
102 *      REQSET  valueで指定したカラムの値をキーに、リクエスト変数から値を取出し、セットします。
103 *      SEQSET  valueの初期値を利用して、1レコードごとに、+1した値をセットします。
104 *      PREFIX  valueの値を後ろから検索し、指定のカラム値の前半部分を取得します(記号は含みません)。
105 *      SUFIX   valueの値を後ろから検索し、指定のカラム値の後半部分を取得します(記号は含みません)。
106 *      その他  カラムのDBType の valueAction メソッドを呼び出します。自由に設定可能です。
107 *
108 * @og.group 画面登録
109 *
110 * @version  4.0
111 * @author       Kazuhiko Hasegawa
112 * @since    JDK5.0,
113 */
114public class ColumnSetTag extends CommonTagSupport {
115        /** このプログラムのVERSION文字列を設定します。   {@value} */
116        private static final String VERSION = "6.7.4.1 (2017/02/17)" ;
117        private static final long serialVersionUID = 674120170217L ;
118
119        private String columnId         ;
120        private String conditionKey ;
121
122        /**
123         * デフォルトコンストラクター
124         *
125         * @og.rev 6.4.2.0 (2016/01/29) PMD refactoring. Each class should declare at least one constructor.
126         */
127        public ColumnSetTag() { super(); }              // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。
128
129        /**
130         * Taglibの開始タグが見つかったときに処理する doStartTag() を オーバーライドします。
131         *
132         * @og.rev 3.6.0.6 (2004/10/22) columnNo に伴なう削除
133         * @og.rev 5.7.7.2 (2014/06/20) caseKey,caseVal,caseNN,caseNull 属性を追加
134         *
135         * @return      後続処理の指示(SKIP_BODY)
136         */
137        @Override
138        public int doStartTag() {
139                // 5.7.7.2 (2014/06/20) caseKey,caseVal,caseNN,caseNull 属性を追加
140                if( useTag() ) {
141                        final EntryTag entry = (EntryTag)findAncestorWithClass( this,EntryTag.class );
142                        if( entry == null ) {
143                                final String errMsg = "<b>" + getTagName() + "タグは、EntryTag のBODY部に記述される必要があります。</b>";
144                                throw new HybsSystemException( errMsg );
145                        }
146
147                        final Attributes standardAttri = getAttributes();
148                        final String[] clms = StringUtil.csv2Array( columnId );
149                        for( int i=0; i<clms.length; i++ ) {
150                                // 6.1.1.0 (2015/01/17) Attributesの連結記述
151                                entry.setAttributes(
152                                        new Attributes( standardAttri )
153                                                .set( "columnId"        , clms[i] )
154                                                .set( "conditionKey", nval( conditionKey,clms[i] ) )    // conditionKey が null の場合は、columnId が設定される。
155                                );
156                        }
157                }
158
159                return SKIP_BODY ;
160        }
161
162        /**
163         * タグリブオブジェクトをリリースします。
164         * キャッシュされて再利用されるので、フィールドの初期設定を行います。
165         *
166         * @og.rev 2.0.0.4 (2002/09/27) カスタムタグの release() メソッドを、追加
167         * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。release2() を doEndTag()で呼ぶ。
168         * @og.rev 3.6.0.6 (2004/10/22) columnNo に伴なう変更
169         *
170         */
171        @Override
172        protected void release2() {
173                super.release2();
174                columnId         = null;
175                conditionKey = null;
176        }
177
178        /**
179         * 【TAG】コマンド (INSERT,COPY,MODIFY,DELETE,ENTRY,CHANGE,RESET,ALLACTION)を設定します。
180         *
181         * @og.tag
182         * 上位の EntryTag のコマンドと一致した場合のみ、処理されます。
183         * ここでは、コマンド文字列の整合性チェックは行っていません。
184         *
185         * @param       command コマンド
186         * @see         <a href="../../../../constant-values.html#org.opengion.hayabusa.taglib.EntryTag.CMD_INSERT">コマンド定数</a>
187         */
188        public void setCommand( final String command ) {
189                set( "command",getRequestParameter( command ) );
190        }
191
192        /**
193         * 【TAG】値をセットします。
194         *
195         * @og.tag
196         * 設定する値をセットします。
197         * 曖昧検索可能フィールド(aimai)の影響で、パラメータに、"%" がくるので、前後の "%" を削除します。
198         * 今は、"%" を前後にセットする方法は、ありません(無条件削除のみ)。
199         *
200         * @og.rev 6.7.4.1 (2017/02/17) 曖昧検索可能フィールドで、"%" がそのままセットされてしまうため、削除します。
201         *
202         * @param       value 値
203         */
204        public void setValue( final String value ) {
205
206                String reqVal = getRequestParameter( value );
207
208                if( reqVal != null ) {
209                        int len = reqVal.length();
210                        if( len > 0 && reqVal.charAt(0) == '%' ) {
211                                reqVal = reqVal.substring(1);                           // 先頭の "%" を削除
212                                len-- ;
213                        }
214
215                        if( len > 0 && reqVal.charAt(len-1) == '%' ) {
216                                reqVal = reqVal.substring( 0,len-1 );           // 末尾の "%" を削除
217                        }
218                }
219
220                set( "value" , reqVal );
221        }
222
223        /**
224         * 【TAG】アクション(DEFAULT/CLEAR/ADD/SET/NULLSET/LOWER/UPPER/COPY/TBLSET/TBLNULLSET/WRTCTRL/DBMENU/REQSET/SEQSET/PREFIX/SUFIX)をセットします。
225         *
226         * @og.tag
227         * ここでは、アクション文字列の整合性チェックを行っておりません。
228         *
229         * DEFAULT カラムリソースで定義した初期値をセットします。
230         * CLEAR   値をクリア(ゼロストリング &quot;&quot; )します。
231         * ADD     現在の値を +1 します。  0 ⇒ 1 , A ⇒ B , 9 ⇒ 10。value属性と併用すれば、指定の値を加算できます。
232         * SET     value で設定した値を 新しい値として登録します。
233         * NULLSET 元の値が NULL の場合だけ、value で設定した新しい値を登録します。
234         * LOWER   小文字に変換します。
235         * UPPER   大文字に変換します。
236         * COPY    value にコピー元のカラムIDをセットすれば、その値を代入します。
237         * TBLSET  DBTableModel の内容を取り込んで指定の columnId カラムに設定します。[カラム名] で指定できます。
238         * TBLNULLSET 元の値が NULL の場合だけ、TBLSETを実行します。      6.9.9.0 (2018/08/20) 追加
239         * WRTCTRL writableControl を使用したカラムデータの先頭アンダーバーを削除します。
240         * DBMENU  DBMENUでパラメータ設定(コロン連結文字)を使用したカラムデータの先頭データのみにします。
241         * REQSET  valueで指定したカラムの値をキーに、リクエスト変数から値を取出し、セットします。
242         * SEQSET  valueの初期値を利用して、1レコードごとに、+1した値をセットします。
243         * PREFIX  valueの値を後ろから検索し、指定のカラム値の前半部分を取得します(記号は含みません)。
244         * SUFIX   valueの値を後ろから検索し、指定のカラム値の後半部分を取得します(記号は含みません)。
245         * その他  カラムのDBType の valueAction メソッドを呼び出します。自由に設定可能です。
246         *
247         * @param       action アクション文字列
248         * @see         <a href="../../../../constant-values.html#org.opengion.hayabusa.taglib.EntryTag.ACT_DEFAULT">アクション定数</a>
249         */
250        public void setAction( final String action ) {
251                set( "action",getRequestParameter( action ) );
252        }
253
254        /**
255         * 【TAG】カラムIDをセットします(複数指定時は、CSV形式で設定する)。
256         *
257         * @og.tag
258         * 処理を適用するカラムIDを指定します。
259         * 全く同じ内容を設定する場合には、カラム名をCSV形式で
260         * 複数指定することが可能です。
261         *
262         * @og.rev 3.6.0.6 (2004/10/22) columnNo に伴なう変更
263         *
264         * @param       clmid カラムID
265         */
266        public void setColumnId( final String clmid ) {
267                columnId = getRequestParameter( clmid );
268        }
269
270        /**
271         * 【TAG】条件判定するカラムIDを指定します(初期値:null)。
272         *
273         * @og.tag
274         * 指定のカラムIDの値と、conditionList の値を比較して、
275         * 存在する場合は、action処理を実行します。
276         * 例えば、初期値設定(action="DEFAULT")で、値が "0" の場合だけ適用するような
277         * ケースに使用できます。
278         * 指定しない場合は、columnId と同じキーになります。
279         * 注意:columnId は、CSV形式で複数同時に指定できます。その場合は、
280         * conditionKey には、複数設定する機能はありませんので、全カラムに
281         * 同一カラムを使用する場合は、conditionKey に値を設定できます。
282         * 値を設定しない場合は、自動的に、columnId と同一になります。
283         *
284         * @og.rev 3.6.0.6 (2004/10/22) 新規追加
285         *
286         * @param       key カラムID
287         * @see         #setConditionList( String )
288         */
289        public void setConditionKey( final String key ) {
290                conditionKey = nval( getRequestParameter( key ),null ) ;
291        }
292
293        /**
294         * 【TAG】条件判定する値のリストを、"|"で区切って登録します(初期値:無条件)。
295         *
296         * @og.tag
297         * conditionKey とペアで指定します。ここには、カラムの設定値のリストを
298         * 指定することで、複数条件(OR結合)での比較を行い、リストにカラム値が
299         * 存在する場合のみ、action処理を実行します。
300         * 設定しない場合は、無条件に実行します。
301         *
302         * @og.rev 3.6.0.6 (2004/10/22) 新規追加
303         *
304         * @param       list 条件判定する値("|"区切)
305         * @see         #setConditionKey( String )
306         */
307        public void setConditionList( final String list ) {
308                set( "conditionList","|" + getRequestParameter( list ) + "|" );
309        }
310
311        /**
312         * 【TAG】(通常は使いません)カラムIDが存在しないときに無視するかどうかを指定します(初期値:true)。
313         *
314         * @og.tag
315         * カラムセットする場合は、DBTableModel に存在するカラムに対してのみ、
316         * 処理を適用するべきで、通常存在しないカラムを使用した場合は、Exception が
317         * throw されます。(strictCheck="true" 初期値の動作です。)
318         * ところが、動的テーブル検索などでカラムが不特定な場合、DBTableModel に
319         * 存在しない場合に、無視したい場合があります。その場合は、strictCheck="false"
320         * に設定すると、カラムが存在しない場合は、エラーにせず、無視します。
321         * 初期値は、true:厳格に処理する です。
322         *
323         * @og.rev 4.0.0.0 (2006/09/31) 新規追加
324         *
325         * @param       strict 厳格処理 [true:厳格に処理する/false:エラーを無視する]
326         */
327        public void setStrictCheck( final String strict ) {
328                set( "strictCheck",getRequestParameter( strict ) );
329        }
330
331        /**
332         * このオブジェクトの文字列表現を返します。
333         * 基本的にデバッグ目的に使用します。
334         *
335         * @return このクラスの文字列表現
336         * @og.rtnNotNull
337         */
338        @Override
339        public String toString() {
340                return ToString.title( this.getClass().getName() )
341                                .println( "VERSION"             ,VERSION                )
342                                .println( "columnId"    ,columnId               )
343                                .println( "conditionKey",conditionKey   )
344                                .println( "Other..."    ,getAttributes().getAttribute() )
345                                .fixForm().toString() ;
346        }
347}