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.db;
017
018import java.util.HashMap;
019import java.util.Locale;
020import java.util.Map;
021import java.util.LinkedHashMap ;
022import java.util.Map.Entry;
023
024import org.opengion.fukurou.util.ErrorMessage;
025import org.opengion.fukurou.db.Transaction;
026import org.opengion.hayabusa.resource.ResourceManager;
027import org.opengion.hayabusa.common.HybsSystemException;
028
029/**
030 * AbstractTableFilter は、TableUpda インターフェースを継承した、DBTableModel 処理用の
031 * Abstract実装クラスです。
032 *
033 * @og.rev 5.5.2.6 (2012/05/25) protected変数をprivateに変更。インターフェースにメソッド追加
034 *
035 * @version  0.9.0  2000/10/17
036 * @author   Kazuhiko Hasegawa
037 * @since    JDK1.1,
038 */
039abstract public class AbstractTableFilter implements TableFilter {
040
041        /** CR 定義 */
042//      5.5.2.6 (2012/05/25) I/F 側に移動
043//      protected static final String CR        = HybsSystem.CR ;       // 5.1.1.0 (2009/12/01) CR 定義をここで行う。
044
045//      protected DBTableModel  table           = null;
046//      protected String                modifyType      = null;
047//      protected int[]                 rowNo           = null;
048//      protected boolean               isDebug         = false;
049//      protected ApplicationInfo appInfo       = null; // 5.1.9.0 (2010/08/01) 廃止
050//      protected Transaction   tran            = null; // 5.1.9.0 (2010/08/01) 追加
051//      protected String                sql                     = null; // 4.2.4.0 (2008/06/23)
052//      protected String                dbid            = null; // 4.2.4.0 (2008/06/23)
053//      protected ResourceManager resource      = null; // 4.3.7.4 (2009/07/01)
054
055        // 5.5.2.6 (2012/05/25) protected変数をprivateに変更。インターフェースにメソッド追加
056        private DBTableModel    table           = null;
057        private String                  modifyType      = null;
058        private int[]                   rowNo           = null;
059        private boolean                 isDebug         = false;
060        private Transaction             tran            = null; // 5.1.9.0 (2010/08/01) 追加
061        private String                  sql                     = null; // 4.2.4.0 (2008/06/23)
062        private String                  dbid            = null; // 4.2.4.0 (2008/06/23)
063        private ResourceManager resource        = null; // 4.3.7.4 (2009/07/01)
064
065        private int                     errCode         = ErrorMessage.OK;
066        private ErrorMessage    errMessage      = null;
067
068        private final Map<String,String>  keysVals        = new HashMap<String,String>();
069
070        // 5.6.6.0 (2013/07/05) keys の整合性チェックを行います。
071        protected final Map<String,String> keysMap = new LinkedHashMap<String,String>();
072
073        /**
074         * デフォルトコンストラクター
075         * ここでは、keys の整合性チェックを行うための初期設定を行う、init( Map&lt;String,String&gt; )
076         * メソッドを呼び出します。
077         * init( Map&lt;String,String&gt; ) メソッドは、各サブクラスで実装が必要です。
078         *
079         * @og.rev 5.6.6.1 (2013/07/12) keys の整合性チェック対応
080         */
081        public AbstractTableFilter() {
082                init( keysMap );
083        }
084
085        /**
086         * keys の整合性チェックを行うための初期設定を行います。
087         * ここでは何もしません。必要であれば、各サブクラスに実装しておきます。
088         *
089         * @og.rev 5.6.6.1 (2013/07/12) keys の整合性チェック対応
090         *
091         * @param       keysMap keys の整合性チェックを行うための Map
092         */
093        protected void init( final Map<String,String> keysMap ) {}
094        
095        /**
096         * keys の整合性チェックを行うための初期設定を行います。
097         * サブクラスのコンストラクタ内で、設定するようにしてください。
098         * V6ではinitがなくなりましたが、V5は互換性のため残しておきます。
099         *
100         * @og.rev 5.9.16.2 (2017/1/28) 6.4.1.1 (2016/01/16) keys の整合性チェック対応
101         *
102         * @param       key  整合性チェックを行うための keysMap に設定するキー
103         * @param       cmnt 整合性チェックを行うための キー の説明
104         */
105        protected void initSet( final String key , final String cmnt ) {
106                keysMap.put( key , cmnt );
107        }
108
109        /**
110         * DBTableModel をセットします。
111         *
112         * @param       table DBTableModelオブジェクト
113         */
114        public void setDBTableModel( final DBTableModel table ) {
115                this.table = table;
116        }
117
118        /**
119         * DBTableModel を取得します。
120         *
121         * @og.rev 5.5.2.6 (2012/05/25) インターフェースにgetterメソッド追加
122         *
123         * @return      内部のDBTableModel
124         */
125        public DBTableModel getDBTableModel() {
126                return table;
127        }
128
129        /**
130         * データ処理の方法(A:追加 C:更新 D:削除)を指定します。
131         *
132         * 通常は、DBTableModel に自動設定されている modifyType を元に、データ処理方法を
133         * 選別します。(A:追加 C:更新 D:削除)
134         * この場合、行単位で modifyType の値を取得して判別する必要がありますが、一般には
135         * 処理対象は、全件おなじ modifyType である可能性が高いです。
136         * また、selectedAll などで強制的に全件処理対象とする場合は、modifyType に値が
137         * 設定さていません。その様な場合に外部より modifyType を指定します。
138         * 初期値は、自動判定 です。
139         *
140         * @og.rev 5.5.2.6 (2012/05/25) 廃止
141         *
142         * @param  type データ処理の方法(A:追加 C:更新 D:削除)
143         */
144        public void setModifyType( final String type ) {
145                modifyType = type;
146        }
147
148        /**
149         * データ処理の方法(A:追加 C:更新 D:削除)を取得します。
150         *
151         * 初期値は、自動判定 です。
152         *
153         * @og.rev 5.5.2.6 (2012/05/25) インターフェースにgetterメソッド追加
154         *
155         * @return  データ処理の方法(A:追加 C:更新 D:削除)
156         */
157        public String getModifyType() {
158                return modifyType ;
159        }
160
161        /**
162         * キーと値のペアの変数配列を受け取ります。
163         *
164         * ここでは、この方式以外に、パラメーターMapを受け取る方法もあります。
165         * この受け取る時に、キーを大文字化します。TableFilter の keys は、
166         * 大文字のみで定義しておくことで、HTMLやWindows世代の曖昧な表記方法に
167         * 対応しています。(unixやxmlのような厳格な方が好きですけど)
168         *
169         * keys,vals とパラメーターMapを同時に指定した場合は、両方とも有効です。
170         * ただし、キーが重複した場合は、不定と考えてください。
171         *
172         * @og.rev 5.6.6.0 (2013/07/05) keys の整合性チェックを行います。
173         *
174         * @param   keys キー配列
175         * @param   vals 値配列
176         * @see         #setParamMap( Map  )
177         */
178        public void setKeysVals( final String[] keys,final String[] vals ) {
179                if( keys != null && vals != null ) {
180                        for( int i=0; i<keys.length; i++ ) {
181                                // 5.6.6.0 (2013/07/05) 共通のセッターメソッド経由で登録します。
182//                              keysVals.put( keys[i].toUpperCase(Locale.JAPAN),vals[i] );
183                                setKeyVal( keys[i],vals[i] );
184                        }
185                }
186        }
187
188        /**
189         * キーと値のペアを受け取り、内部の keysVals マップに追加します。
190         *
191         * キーか値のどちらかが null の場合は、何もしません。つまり、val に
192         * null をセットすることはできません。
193         *
194         * このメソッドは、setKeysVals( String[] ,String[] ) メソッドと、
195         * setParamMap( Map<String,String> ) メソッドの両方から、使用します。
196         * 処理を行うに当たり、下記の処理を行います。
197         * 1.キーを大文字化します。
198         * 2.各クラスの keys と整合性チェックを行います。
199         *
200         * ただし、setKeysVals と setParamMap の登録順は、不定と考えてください。
201         * 両方に同じキーを指定すると、どちらの値がセットされたかは、不定です。
202         *
203         * @og.rev 5.6.6.0 (2013/07/05) keys の整合性チェックを行います。
204         *
205         * @param   key キー文字列(null の場合は、処理しない)
206         * @param   val 値文字列(null の場合は、処理しない)
207         * @see         #setKeysVals( String[] ,String[] )
208         * @see         #setParamMap( Map )
209         */
210        private void setKeyVal( final String key,final String val ) {
211                // key か val かどちらかが null の場合は、処理を行わない。
212                if( key == null || val == null ) { return; }
213
214                String upKey = key.toUpperCase(Locale.JAPAN);
215
216                if( keysMap.containsKey( upKey ) ) {            // keysMap は、各サブクラスで定義
217                        keysVals.put( upKey,val );
218                }
219                else {
220                        String BR = "<br />" + CR ;
221                        StringBuilder errMsg = new StringBuilder();
222                        errMsg.append( BR )
223                                  .append( "指定のキーは、この tableFilter では、使用できません。" ).append( BR )
224                                  .append( "  class=[" ).append( getClass().getName() ).append( "]" ).append( BR )
225                                  .append( "  key  =[" ).append( key                              ).append( "]" ).append( BR )
226                                  .append( "  ======== usage keys ======== " ).append( BR ) ;
227                        for( Map.Entry<String, String> entry : keysMap.entrySet() ) {
228                                errMsg.append( "  " ).append( entry.getKey() ).append( " : " )
229                                                                         .append( entry.getValue() ).append( BR ) ;
230                        }
231                        errMsg.append( "  ============================ " ).append( BR );
232
233                        throw new HybsSystemException( errMsg.toString() );
234                }
235        }
236
237        /**
238         * 選択された行番号の配列をセットします。
239         *
240         * 表示データの HybsSystem.ROW_SELECTED_KEY を元に、選ばれた 行を
241         * 処理の対象とします。
242         *
243         * @param   rowNoTmp 行番号配列
244         */
245        public void setParameterRows( final int[] rowNoTmp ) {
246                if( rowNoTmp != null ) {
247                        int size = rowNoTmp.length ;
248                        rowNo = new int[size];
249                        System.arraycopy( rowNoTmp,0,rowNo,0,size );
250                }
251        }
252
253        /**
254         * 選択された行番号の配列を取得します。
255         *
256         * 表示データの HybsSystem.ROW_SEL_KEY を元に、選ばれた 行を
257         * 処理の対象とします。
258         *
259         * @og.rev 5.5.2.6 (2012/05/25) インターフェースにgetterメソッド追加
260         *
261         * @return   行番号の配列
262         */
263        public int[] getParameterRows() {
264                return (rowNo != null ) ? rowNo.clone() : null ;
265        }
266
267        /**
268         * アクセスログ取得の為,ApplicationInfoオブジェクトを設定します。
269         *
270         * @og.rev 3.8.7.0 (2006/12/15) 新規追加
271         * @og.rev 5.1.9.0 (2010/08/01) Transaction 対応 のため、廃止
272         *
273         * @param   appInfo ApplicationInfo
274         */
275//      public void setApplicationInfo( final ApplicationInfo appInfo ) {
276//              this.appInfo = appInfo;
277//      }
278
279        /**
280         * アクセスログ取得の為,Transactionオブジェクトを設定します。
281         *
282         * @og.rev 5.1.9.0 (2010/08/01) Transaction 対応(新規追加)
283         *
284         * @param   tran Transactionオブジェクト
285         */
286        public void setTransaction( final Transaction tran ) {
287                this.tran = tran;
288        }
289
290        /**
291         * アクセスログ取得の為,Transactionオブジェクトを取得します。
292         *
293         * @og.rev 5.1.9.0 (2010/08/01) Transaction 対応(新規追加)
294         * @og.rev 5.5.2.6 (2012/05/25) インターフェースにgetterメソッド追加
295         *
296         * @return   Transactionオブジェクト
297         */
298        public Transaction getTransaction() {
299                return tran;
300        }
301
302        /**
303         * DBIDを指定します。
304         *
305         * @og.rev 4.2.4.0 (2008/06/23) 新規追加
306         *
307         * @param dbid 接続先ID
308         */
309        public void setDbid( final String dbid ) {
310                this.dbid = dbid;
311        }
312
313        /**
314         * DBIDを取得します。
315         *
316         * @og.rev 4.2.4.0 (2008/06/23) 新規追加
317         * @og.rev 5.5.2.6 (2012/05/25) インターフェースにgetterメソッド追加
318         *
319         * @return DBID(接続先情報)
320         */
321        public String getDbid() {
322                return dbid;
323        }
324
325        /**
326         * ボディー部分のSQLを指定します。
327         *
328         * @og.rev 4.2.4.0 (2008/06/23) 新規追加
329         *
330         * @param sql ボディー部分のSQL
331         */
332        public void setSql( final String sql ) {
333                this.sql = sql;
334        }
335
336        /**
337         * ボディー部分のSQLを取得します。
338         *
339         * @og.rev 4.2.4.0 (2008/06/23) 新規追加
340         * @og.rev 5.5.2.6 (2012/05/25) インターフェースにgetterメソッド追加
341         *
342         * @return ボディー部分のSQL
343         */
344        public String getSql() {
345                return sql;
346        }
347
348        /**
349         * パラメーターMapを指定します。
350         *
351         * keys,vals と パラメーターMapを同時に指定した場合は、両方とも有効です。
352         * ただし、キーが重複した場合は、不定と考えてください。
353         *
354         * この受け取る時に、キーを大文字化します。TableFilter の keys は、
355         * 大文字のみで定義しておくことで、HTMLやWindows世代の曖昧な表記方法に
356         * 対応しています。(unixやxmlのような厳格な方が好きですけど)
357         *
358         * @og.rev 5.6.5.2 (2013/06/21) 新規追加
359         * @og.rev 5.6.6.0 (2013/07/05) keys の整合性チェックを行います。
360         *
361         * @param paramMap パラメーターMap
362         * @see         #setKeysVals( String[] ,String[] )
363         */
364        public void setParamMap( final Map<String,String> paramMap ) {
365                if( paramMap != null ) {
366//                      keysVals.putAll( paramMap );
367                        // 5.6.6.0 (2013/07/05) Map を一つづつ回して登録します。
368                        for( Map.Entry<String, String> entry : paramMap.entrySet() ) {
369                                setKeyVal( entry.getKey(),entry.getValue() );
370                        }
371                }
372        }
373
374        /**
375         * リソースオブジェクトを指定します。
376         *
377         * @og.rev 4.3.7.4 (2009/07/01) 新規追加
378         *
379         * @param resource リソースオブジェクト
380         */
381        public void setResource( final ResourceManager resource ) {
382                this.resource = resource;
383        }
384
385        /**
386         * リソースオブジェクトを取得します。
387         *
388         * @og.rev 4.3.7.4 (2009/07/01) 新規追加
389         * @og.rev 5.5.2.6 (2012/05/25) インターフェースにgetterメソッド追加
390         *
391         * @return リソースオブジェクト
392         */
393        public ResourceManager getResource() {
394                return resource;
395        }
396
397        /**
398         * デバッグ情報を表示するかどうか[true/false]を指定します。
399         * true でデバッグ情報を表示します。
400         *
401         * @param   flag  [true:出力する/それ以外:しない]
402         */
403        public void setDebug( final boolean flag ) {
404                isDebug = flag;
405        }
406
407        /**
408         * デバッグ情報を表示するかどうかを取得します。
409         * true でデバッグ情報を表示します。
410         *
411         * @og.rev 5.5.2.6 (2012/05/25) インターフェースにgetterメソッド追加
412         *
413         * @return  デバッグ情報(true:デバッグ情報を出力する)
414         */
415        public boolean isDebug() {
416                return isDebug ;
417        }
418
419        /**
420         * エラーコード を取得します。
421         * エラーコード は、ErrorMessage クラスで規定されているコードです。
422         *
423         * @return   エラーコード
424         */
425        public int getErrorCode() {
426                return errCode;
427        }
428
429        /**
430         * エラーメッセージオブジェクト を取得します。
431         *
432         * @return   エラーメッセージオブジェクト
433         */
434        public ErrorMessage getErrorMessage() {
435                return errMessage;
436        }
437
438        /**
439         * タイトルとエラーコードを指定して、エラーメッセージオブジェクト を作成します。
440         * すでに、作成済みの場合は、作成済みのオブジェクトを、まだ、未作成の場合は、
441         * 新規に作成します。
442         *
443         * @param       title   タイトル
444         * @param       code    エラーコード
445         *
446         * @return      エラーメッセージオブジェクト
447         */
448        protected ErrorMessage makeErrorMessage( final String title,final int code ) {
449                if( errMessage == null ) {
450                        errMessage = new ErrorMessage( title );
451                }
452                if( errCode < code ) { errCode = code; }
453                return errMessage;
454        }
455
456        /**
457         *  カラム名配列(String[])より、対応するカラムNo配列(int[])を作成します。
458         *
459         * @param       nameArray カラム名配列
460         *
461         * @return      カラムNo配列
462         */
463        protected int[] getTableColumnNo( final String[] nameArray ) {
464                int[] clmNo = new int[ nameArray.length ];
465                for( int i=0; i<clmNo.length; i++ ) {
466                        clmNo[i] = table.getColumnNo( nameArray[i] );
467                }
468                return clmNo;
469        }
470
471        /**
472         *  設定されたパラメータキーに対する値を取得します。
473         * 引数、および、パラメータが null の場合は、 null を返します。
474         *
475         * @param       key     パラメータキー
476         *
477         * @return      パラメータ値
478         */
479        protected String getValue( final String key ) {
480                return keysVals.get( key );
481        }
482}