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