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     */
016    package org.opengion.hayabusa.db;
017    
018    import org.opengion.fukurou.util.StringUtil;
019    import org.opengion.fukurou.model.NativeType;
020    import org.opengion.hayabusa.common.HybsSystem;
021    import org.opengion.hayabusa.common.HybsSystemException;
022    
023    import java.util.List;
024    import java.util.ArrayList;
025    import java.util.Map;
026    import java.util.HashMap;
027    import java.util.Set;
028    import java.util.HashSet;
029    import java.util.Arrays;
030    import java.util.Locale ;
031    
032    /**
033     * DBTableModel インターフェースを継承した TableModel の実?ラスです?
034     * sql? execute( query ) する事により,??タベ?スを検索した結果?
035     * DBTableModel に割り当てます?
036     *
037     * メソ?を宣?て??
038     * DBTableModel インターフェースは?データベ?スの検索結果(Resultset)をラ??する
039     * インターフェースとして使用して下さ??
040     *
041     * @og.group ??ブル管?
042     *
043     * @version  4.0
044     * @author   Kazuhiko Hasegawa
045     * @since    JDK5.0,
046     */
047    public class DBTableModelImpl implements DBTableModel {
048            /** カラ?ブジェクト??*/
049            protected       DBColumn[]                      dbColumns       = null;
050            /** カラ?称配? */
051            protected       String[]                        names           = null;
052            /** ??タリス?*/
053            protected       List<String[]>            data            = null;
054            /** 行??ー?? */
055            protected       List<DBRowHeader> rowHeader       = null;
056            /** カラ?ドレスマップ情報 */
057            protected       Map<String,Integer> columnMap     = null;
058            /** オーバ?フローフラグ */
059            protected       boolean                         overflow        = false;
060    
061            /** カラ? */
062            protected   int         numberOfColumns = 0;
063    
064            // 3.5.5.5 (2004/04/23) 整合?キー(オブジェクト?作?時刻)追?
065            /** 整合?キー(オブジェクト?作?時刻) */
066            protected       String          consistencyKey  = String.valueOf( System.currentTimeMillis() );
067            private         String[]        lastData                = null;
068            private         int             lastRow                 = -1;
069    
070            // 4.1.2.1 (2008/03/13) カラ??にmustタイプ?を割り当てます?
071            private final   Map<String,Set<String>> mustMap = new HashMap<String,Set<String>>() ;   // 4.3.1.1 (2008/08/23) final?
072    
073            /**
074             * こ?オブジェクトを初期化します?
075             * ??引数???配?を作?します?
076             *
077             * @og.rev 3.1.0.0 (2003/03/20) 実?、Vector ?Hashtable から、ArrayList ?HashMapに、変更?
078             * @og.rev 3.1.0.0 (2003/03/20) 同期メソ?(synchronized付き)を非同期に変更する?
079             *
080             * @param   columnCount カラ?
081             */
082            public void init( final int columnCount ) {
083                    data                    = new ArrayList<String[]>( HybsSystem.BUFFER_MIDDLE );
084                    rowHeader               = new ArrayList<DBRowHeader>( HybsSystem.BUFFER_MIDDLE );
085                    names                   = new String[columnCount];
086                    dbColumns               = new DBColumn[ columnCount ];
087                    numberOfColumns = columnCount;
088                    columnMap               = new HashMap<String,Integer>();
089                    lastRow                 = -1;                           // 3.5.5.7 (2004/05/10)
090            }
091    
092            /**
093             * こ?オブジェクトをヘッ??部?コピ?し???タを?期化します?
094             * これは、カラ?どヘッ??系の??は、?と同じオブジェクトを共有し?
095             * ??タ部のみ空にした DBTableModel を作?することを意味します?
096             * こ?際?consistencyKey も??します?で、整合?は崩れな???
097             * ??タ登録を行う?があります?
098             *
099             * @og.rev 4.0.0.0 (2007/06/28) 新規作?
100             *
101             * @return  DBTableModelオブジェク?
102             */
103            public DBTableModel newModel() {
104                    DBTableModelImpl table = new DBTableModelImpl();
105    
106                    table.data                              = new ArrayList<String[]>( HybsSystem.BUFFER_MIDDLE );
107                    table.rowHeader                 = new ArrayList<DBRowHeader>( HybsSystem.BUFFER_MIDDLE );
108                    table.names                             = names;
109                    table.dbColumns                 = dbColumns;
110                    table.numberOfColumns   = numberOfColumns;
111                    table.columnMap                 = columnMap;
112                    table.lastRow                   = -1;
113                    table.consistencyKey    = consistencyKey;
114    
115                    return table ;
116            }
117    
118            /**
119             * カラ?配?を返します?
120             *
121             * @og.rev 3.0.0.0 (2002/12/25) カラ?配?を取得するメソ?を追?る?
122             * @og.rev 3.5.6.0 (2004/06/18) 配?をそのまま返さずに、clone して返します?
123             * @og.rev 3.6.0.0 (2004/09/22) names ?null の場合?、?期設定エラーとします?
124             *
125             * @return      カラ?配?
126             */
127            public String[] getNames() {
128                    if( names != null ) {
129                            return names.clone();
130                    }
131    
132                    String errMsg = "カラ?配?が?初期化されて?せん?;
133                    throw new HybsSystemException( errMsg );
134            }
135    
136            //////////////////////////////////////////////////////////////////////////
137            //
138            //   DBTableModelImpl 独自の実??
139            //
140            //////////////////////////////////////////////////////////////////////////
141    
142            /**
143             * column に対応し?値を登録します?
144             * column には、番号ではなく、ラベルを指定します?
145             * ??行番号が??の??タ件数より多い場合?、データを追?ます?
146             *
147             * @og.rev 3.1.0.0 (2003/03/20) 同期メソ?(synchronized付き)を非同期に変更する?
148             *
149             * @param   aRow    値が変更される?
150             * @param   columnName    値が変更されるカラ?
151             * @param   value   新しい値。null も可
152             */
153            public void setValue( final int aRow, final String columnName, final String value ) {
154                    int aColumn = getColumnNo( columnName );
155                    int size = getRowCount();
156                    if( size > aRow ) {
157                            setRowHeader( aRow,UPDATE_TYPE );
158                            setValueAt( value , aRow, aColumn );
159                    }
160                    else {
161                            for( int i = 0; i< (aRow-size)+1; i++ ) {
162                                    String[] columnValues = new String[ numberOfColumns ];
163                                    for(int j = 0; j < numberOfColumns; j++) {           // 3.5.5.7 (2004/05/10)
164                                            columnValues[j] = "";
165                                    }
166                                    addColumnValues( columnValues );
167                            }
168                            setValueAt( value , aRow, aColumn );
169                    }
170            }
171    
172            /**
173             * 行を削除します?
174             * 物?除ではなく?論理削除です?
175             * ??タを取り込?とは可能です?
176             *
177             * @og.rev 3.1.0.0 (2003/03/20) 同期メソ?(synchronized付き)を非同期に変更する?
178             *
179             * @param   aRow    論理削除される?
180             */
181            public void rowDelete( final int aRow ) {
182                    setRowHeader( aRow,DELETE_TYPE );
183            }
184    
185            /**
186             * row にあるセルのオブジェクト?を置き換えて、行を削除します?
187             * 物?除ではなく?論理削除です?
188             * 値を置き換えた??タを取り込?とが可能です?
189             *
190             * @og.rev 3.5.4.2 (2003/12/15) 新規追?
191             *
192             * @param   values  新しい配?値?
193             * @param   aRow    論理削除される?
194             *
195             */
196            public void rowDelete( final String[] values, final int aRow ) {
197                    if( numberOfColumns == values.length ) {                // 3.5.5.7 (2004/05/10)
198                            setRowHeader( aRow,DELETE_TYPE );
199                            data.set( aRow,values );
200                            lastRow = -1;                           // 3.5.5.7 (2004/05/10)
201                    }
202                    else {
203                            String errMsg = "カラ?の個数が不??です? [" + numberOfColumns + "] : [" + values.length + "]"
204                                                                    + " values=" + StringUtil.array2csv( values ) ;         // 5.1.8.0 (2010/07/01) errMsg 修正
205                            throw new HybsSystemException( errMsg );
206                    }
207            }
208    
209            /**
210             * 行を物?除します?
211             * メモリ上で編?る?合に使用しますが,?アプリケーションからの
212             * 使用は、物?除の為,お勧めいたしません?
213             *
214             * @og.rev 3.1.0.0 (2003/03/20) 同期メソ?(synchronized付き)を非同期に変更する?
215             *
216             * @param   aRow    物?除される?
217             *
218             */
219            public void removeValue( final int aRow ) {
220                    data.remove( aRow );
221                    rowHeader.remove( aRow );
222                    lastRow = -1;                           // 3.5.5.7 (2004/05/10)
223            }
224    
225            //////////////////////////////////////////////////////////////////////////
226            //
227            //   DBTableModel インターフェースの実??
228            //
229            //////////////////////////////////////////////////////////////////////////
230    
231            /**
232             * カラ??ラベル名を返します?
233             * カラ???名に対して,見える形の??を返します?
234             * ?には,リソースバンドルと?せて,?ロケール毎にラベル?
235             * ?えます?
236             *
237             * @param   column カラ?号
238             *
239             * @return  カラ??ラベル?
240             */
241            public String getColumnLabel( final int column ) {
242                    return dbColumns[column].getLabel();
243            }
244    
245            /**
246             * row および column にあるセルの属?値をStringに変換して返します?
247             *
248             * @og.rev 3.5.5.7 (2004/05/10) 連続同?row アクセスのキャ?ュ利用対?
249             *
250             * @param   aRow     値が参照される?
251             * @param   aColumn  値が参照される?
252             *
253             * @return  ?されたセルの値 String
254             */
255            public String getValue( final int aRow, final int aColumn ) {
256                    if( aRow != lastRow ) {
257                            lastData = data.get(aRow);
258                            lastRow = aRow ;
259                    }
260                    return lastData[aColumn] ;
261            }
262    
263            /**
264             * row および columnName にあるセルの属?値をStringに変換して返します?
265             *
266             * @param   aRow       値が参照される?
267             * @param   columnName 値が参照されるカラ?
268             *
269             * @return  ?されたセルの値 String
270             * @see #getValue( int , int )
271             */
272            public String getValue( final int aRow, final String columnName ) {
273                    return getValue( aRow,getColumnNo( columnName ) );
274            }
275    
276            /**
277             * カラ??にカラ?ブジェクトを割り当てます?
278             * カラ?ブジェクト??ラベル?ー?ど?そのカラ?報?
279             * 保持したオブジェクトです?
280             *
281             * @og.rev 3.1.0.0 (2003/03/20) 同期メソ?(synchronized付き)を非同期に変更する?
282             *
283             * @param   clm        ヘッ??を適応するカラ??
284             * @param   dbColumn   カラ?ブジェク?
285             */
286            public void setDBColumn( final int clm, final DBColumn dbColumn ) {
287                    dbColumns[clm] = dbColumn;
288                    names[clm]     = dbColumn.getName();
289                    columnMap.put( names[clm].toUpperCase(Locale.JAPAN),Integer.valueOf( clm ) );
290            }
291    
292            /**
293             * カラ??のカラ?ブジェクトを返します?
294             * カラ?ブジェクト??ラベル?ー?ど?そのカラ?報?
295             * 保持したオブジェクトです?
296             *
297             * @param       clm     ヘッ??を適応するカラ??
298             *
299             * @return      カラ?ブジェク?
300             */
301            public DBColumn getDBColumn( final int clm ) {
302                    return dbColumns[ clm ];
303            }
304    
305            /**
306             * カラ?ブジェクト?列を返します?
307             * カラ?ブジェクト??ラベル?ー?ど?そのカラ?報?
308             * 保持したオブジェクトです?
309             *
310             * @og.rev 4.0.0.0 (2005/12/31) 新規追?
311             *
312             * @return      カラ?ブジェクト??
313             */
314            public DBColumn[] getDBColumns() {
315                    int size = dbColumns.length;
316                    DBColumn[] clms = new DBColumn[size];
317                    System.arraycopy( dbColumns,0,clms,0,size );
318                    return clms;
319            }
320    
321            /**
322             * カラ?をもとに、そのカラ?号を返します?
323             * カラ?が存在しな??合?? HybsSystemException ?throw します?
324             *
325             * @param   columnName   カラ?
326             *
327             * @return  カラ?号
328             * @see #getColumnNo( String ,boolean )
329             */
330            public int getColumnNo( final String columnName ) {
331                    return getColumnNo( columnName,true );
332            }
333    
334            /**
335             * カラ?をもとに、そのカラ?号を返します?
336             * useThrow が?true の場合?、カラ?が存在しな??合?? HybsSystemException ?
337             * throw します?useThrow が?false の場合?、カラ?が存在しな??合?? -1 を返します?
338             *
339             * @og.rev 4.0.0.0 (2005/12/31) 新規追?
340             *
341             * @param   columnName   カラ?
342             * @param   useThrow     カラ?が存在しな??合に、Exception ?throw するかど?
343             *
344             * @return  カラ?号
345             * @see #getColumnNo( String )
346             */
347            public int getColumnNo( final String columnName,final boolean useThrow ) {
348                    if( columnName != null ) {
349                            Integer no = columnMap.get( columnName.toUpperCase(Locale.JAPAN) );
350                            if( no != null ) { return no.intValue() ; }
351                    }
352    
353                    if( useThrow ) {
354                            String errMsg = "カラ?が存在しません:[" + columnName + "]" ;
355                            throw new HybsSystemException( errMsg );
356                    }
357                    else {
358                            return -1;
359                    }
360            }
361    
362            //////////////////////////////////////////////////////////////////////////
363            //
364            //   DBTableModel クラスのオーバ?ライド部?
365            //
366            //////////////////////////////////////////////////////////////////////////
367    
368            /**
369             * row の下に属?値配?を追?録します?
370             *
371             * @og.rev 3.1.0.0 (2003/03/20) 同期メソ?(synchronized付き)を非同期に変更する?
372             *
373             * @param   values  属?値配?
374             * @param   aRow    値が参照される?
375             *
376             */
377            public void addValues( final String[] values ,final int aRow ) {
378    //              data.add( aRow,values );
379    //              lastRow = -1;                           // 3.5.5.7 (2004/05/10)
380    //
381    //              DBRowHeader rowhed = new DBRowHeader();
382    //              rowhed.setType( INSERT_TYPE );
383    //              rowHeader.add( aRow,rowhed );
384                    addValues( values, aRow, true ); // 4.3.1.0 (2008/09/04)
385            }
386    
387            /**
388             * row の下に属?値配?を追?録します?
389             * isWritableをfalseにした場合?編?可能な状態で追?れます?
390             *
391             * @og.rev 4.3.1.0 (2008/09/04) interface に新規登録
392             *
393             * @param   values  属?値配?
394             * @param   aRow    値が参照される?
395             * @param   isWritable 編?可能な状態で追?るか
396             *
397             */
398            public void addValues( final String[] values ,final int aRow, final boolean isWritable ) {
399                    data.add( aRow,values );
400                    lastRow = -1;                           // 3.5.5.7 (2004/05/10)
401    
402                    DBRowHeader rowhed = new DBRowHeader();
403                    if( isWritable ) {
404                            rowhed.setType( INSERT_TYPE );
405                    }
406                    else {
407                            rowhed.setWritable( false );
408                            rowhed.setChecked( false );
409                    }
410                    rowHeader.add( aRow,rowhed );
411            }
412    
413            /**
414             * row あるセルの属?値配?を追?録します?
415             * これは,初期登録時?みに使用します?
416             *
417             * @og.rev 3.1.0.0 (2003/03/20) 同期メソ?(synchronized付き)を非同期に変更する?
418             *
419             * @param   values  属?値配?
420             *
421             */
422            public void addColumnValues( final String[] values ) {
423                    data.add( values );
424                    lastRow = -1;                           // 3.5.5.7 (2004/05/10)
425                    rowHeader.add( new DBRowHeader() );
426            }
427    
428            //////////////////////////////////////////////////////////////////////////
429            //
430            //             Implementation of the TableModel Interface
431            //
432            //////////////////////////////////////////////////////////////////////////
433    
434            // MetaData
435    
436            /**
437             * カラ?を取得します?
438             *
439             * @param   column  ??のカラ?? 0?番目のカラ?? 1、などとする?
440             *
441             * @return  カラ?
442             *
443             */
444            public String getColumnName( final int column ) {
445                    return names[column];
446            }
447    
448            /**
449             * ??タ??ブル??列?数を返します?
450             *
451             * @return  モ?の列数
452             *
453             */
454            public int getColumnCount() {
455                    return numberOfColumns ;
456            }
457    
458            /**
459             * ??タ??ブル??行?数を返します?
460             *
461             * @return  モ?の行数
462             *
463             */
464            public int getRowCount() {
465                    return data.size() ;
466            }
467    
468            /**
469             * column および row にあるセルのオブジェクト?を設定します?
470             * こ?メソ?は、行番号の?チェ???列番号のチェ?を行いません?
471             * また?登録に際して、更新マ?カー(UPDATE_TYPE?を設定しません?
472             *
473             * @og.rev 3.1.0.0 (2003/03/20) 同期メソ?(synchronized付き)を非同期に変更する?
474             * @og.rev 3.5.3.1 (2003/10/31) インターフェースの見直しにより、private 化する?
475             * @og.rev 4.0.0.0 (2007/05/24) インターフェースの見直しにより、public 化する?
476             *
477             * @param   value   新しい値。null も可
478             * @param   aRow    値が変更される?
479             * @param   aColumn 値が変更される?
480             */
481            public void setValueAt( final String value, final int aRow, final int aColumn ) {
482    //              setRowHeader( aRow,UPDATE_TYPE );
483                    String[] row = data.get(aRow);
484                    row[ aColumn ] = value;
485                    data.set( aRow,row );
486                    lastRow = -1;                           // 3.5.5.7 (2004/05/10)
487            }
488    
489            //////////////////////////////////////////////////////////////////////////
490            //
491            //             DBTableModel 独自追??
492            //
493            //////////////////////////////////////////////////////////////////////////
494    
495            /**
496             * row にあるセルの属?値を?列で返します?
497             *
498             * @param   aRow     値が参照される?
499             *
500             * @return  ?されたセルの属?値
501             *
502             */
503            public String[] getValues( final int aRow ) {
504                    return data.get(aRow);
505            }
506    
507            /**
508             * row にあるセルのオブジェクト?を置き換えます?
509             *
510             * @og.rev 3.1.0.0 (2003/03/20) 同期メソ?(synchronized付き)を非同期に変更する?
511             *
512             * @param   values  新しい配?値?
513             * @param   aRow    値が変更される?
514             *
515             */
516            public void setValues( final String[] values, final int aRow ) {
517                    if( numberOfColumns == values.length ) {                // 3.5.5.7 (2004/05/10)
518                            setRowHeader( aRow,UPDATE_TYPE );
519                            data.set( aRow,values );
520                            lastRow = -1;                           // 3.5.5.7 (2004/05/10)
521                    }
522                    else {
523                            String errMsg = "カラ?の個数が不??です? [" + numberOfColumns + "] : [" + values.length + "]"
524                                                                    + " values=" + StringUtil.array2csv( values ) ;         // 5.1.8.0 (2010/07/01) errMsg 修正
525                            throw new HybsSystemException( errMsg );
526                    }
527            }
528    
529            /**
530             * 変更済みフラグを?に戻します?
531             *
532             * @og.rev 3.1.0.0 (2003/03/20) 同期メソ?(synchronized付き)を非同期に変更する?
533             *
534             * ?には,??タベ?スに??ブルモ?を登録するタイミングで?
535             * 変更済みフラグを?に戻します?
536             *
537             */
538            public void resetModify() {
539                    int size = rowHeader.size() ;
540                    DBRowHeader row ;
541                    for( int i=0; i<size; i++ ) {
542                            row = rowHeader.get( i );
543                            row.clear();
544                    }
545            }
546    
547            /**
548             * 変更済みフラグを?に戻します?
549             *
550             * ?には,??タベ?スに??ブルモ?を登録するタイミングで?
551             * 変更済みフラグを?に戻します?
552             *
553             * @og.rev 3.1.0.0 (2003/03/20) 同期メソ?(synchronized付き)を非同期に変更する?
554             *
555             * @param   aRow     値が参照される?
556             */
557            public void resetModify( final int aRow ) {
558                    DBRowHeader row = rowHeader.get( aRow );
559                    row.clear();
560            }
561    
562            /**
563             * row 単位に変更されたタイ?追?変更/削除)を返します?
564             * タイプ?始めに?登録するとそれ以降に変更はかかりません?
565             * つまり?始めに 追?作?した??タは、その後変更があっても追??ままです?
566             * なにも変更されて???合?, ""(ゼロストリング)を返します?
567             *
568             * @param   aRow     値が参照される?
569             *
570             * @return  変更されたタイプ?値 String
571             *
572             */
573            public String getModifyType( final int aRow ) {
574                    DBRowHeader row = rowHeader.get( aRow );
575                    return row.getType();
576            }
577    
578            /**
579             * row 単位に変更タイ?追?変更/削除)をセ?します?
580             * こ?メソ?では、データのバックア??は取りません?
581             * タイプ?始めに?登録するとそれ以降に変更はかかりません?
582             * なにも変更されて???合?, ""(ゼロストリング)の状態です?
583             *
584             * @param   aRow     値が参照される?
585             * @param   modType  変更タイ?追?変更/削除)
586             *
587             */
588            public void setModifyType( final int aRow,final String modType ) {
589                    DBRowHeader rowhed = rowHeader.get( aRow );
590                    rowhed.setType( modType );
591            }
592    
593            /**
594             * row 単位に変更タイ?追?変更/削除)をセ?します?
595             * セ?すると同時に、データのバックア??を取ります?
596             * タイプ?始めに?登録するとそれ以降に変更はかかりません?
597             * つまり?始めに 追?作?した??タは、その後変更があっても追??ままです?
598             * なにも変更されて???合?, ""(ゼロストリング)の状態です?
599             *
600             * @og.rev 3.5.6.0 (2004/06/18) setBackupData 側で 配?をコピ?して?ため、こちらでは不要?
601             * @og.rev 3.5.6.4 (2004/07/16) protected 化します?
602             *
603             * @param   aRow     値が参照される?
604             * @param   modType  変更タイ?追?変更/削除)
605             */
606            protected void setRowHeader( final int aRow,final String modType ) {
607                    DBRowHeader rowhed = rowHeader.get( aRow );
608    
609                    rowhed.setBackupData( data.get(aRow) );
610                    rowhed.setType( modType );
611            }
612    
613            /**
614             * 変更??タを?期?(??取り込んだ状?に戻します?
615             *
616             * 変更タイ?追?変更/削除)に応じて、??れます?
617             * 追?は、追?れた行を削除します?
618             * 変更時?、変更された行を?戻します?
619             * 削除時?、削除フラグを解除します?
620             * それ以外?場?変更されて????は、なにもしません?
621             *
622             * @og.rev 3.1.0.0 (2003/03/20) 同期メソ?(synchronized付き)を非同期に変更する?
623             * @og.rev 3.5.4.2 (2003/12/15) "DELETE" 時に値を置き換えた場合にUPDATEと同様に戻します?
624             *
625             * @param   aRow    処?戻?取り消す)?
626             */
627            public void resetRow( final int aRow ) {
628                    String modType = getModifyType(aRow) ;
629    
630                    if( modType.equals( INSERT_TYPE ) ) {
631                            data.remove( aRow );
632                            rowHeader.remove( aRow );
633                    }
634                    else if( modType.equals( UPDATE_TYPE ) ||
635                                     modType.equals( DELETE_TYPE ) ) {
636                            DBRowHeader row = rowHeader.get( aRow );
637                            String[] obj = row.getBackupData();
638                            if( obj != null ) { data.set( aRow,obj ); }
639                            row.clear();
640                    }
641                    lastRow = -1;                           // 3.5.5.7 (2004/05/10)
642            }
643    
644            /**
645             * 書込み許可を返します?
646             *
647             * @param   aRow     値が参照される?
648             *
649             * @return  書込み可能(true)?不可能(false)
650             */
651            public boolean isRowWritable( final int aRow ) {
652                    DBRowHeader row = rowHeader.get( aRow );
653                    return row.isWritable();
654            }
655    
656            /**
657             * 行が書き込み可能かど?をセ?します?
658             * ?ォル?およびなにも設定しな??合?, DEFAULT_WRITABLE ?
659             * 与えられて?す?
660             * これ?true の場合?,書込み許可です?(チェ?ボックスを表示)
661             * false の場合?,書込み不許可(チェ?ボックスは表示されません?
662             *
663             * @og.rev 3.1.0.0 (2003/03/20) 同期メソ?(synchronized付き)を非同期に変更する?
664             *
665             * @param   aRow     値が参照される?
666             * @param   rw 書込み可能(true)?不可能(false)
667             */
668            public void setRowWritable( final int aRow ,final boolean rw ) {
669                    DBRowHeader row = rowHeader.get( aRow );
670                    row.setWritable( rw );
671            }
672    
673            /**
674             * 書き込み可能な?rowWritable == true)のチェ?ボックスに対して
675             * 初期値?選択済みか?非選択済みかを返します?
676             *
677             * @param   aRow      値が参照される?
678             *
679             * @return      初期値チェ?ON(true)?チェ?OFF(false)
680             */
681            public boolean isRowChecked( final int aRow ) {
682                    DBRowHeader row = rowHeader.get( aRow );
683                    return row.isChecked();
684            }
685    
686            /**
687             * 書き込み可能な?rowWritable == true)のチェ?ボックスに対して
688             * 初期値?選択済みにするか?非選択済みにするかを?します?
689             *
690             * @og.rev 3.1.0.0 (2003/03/20) 同期メソ?(synchronized付き)を非同期に変更する?
691             *
692             * @param   aRow      値が参照される?
693             * @param   rw チェ?ON(true)?チェ?OFF(false)
694             */
695            public void setRowChecked( final int aRow ,final boolean rw ) {
696                    DBRowHeader row = rowHeader.get( aRow );
697                    row.setChecked( rw );
698            }
699    
700            /**
701             * 行指定?書込み許可を与えます?
702             * 具体的には,チェ?ボックスの表示/非表示を指定します?
703             * これ?true の場合?,書込み許可です?(チェ?ボックスを表示)
704             * false の場合?,書込み不許可(チェ?ボックスは表示されません?
705             * 行毎に書込み許可/不許可を指定する?合?,?カラ?に writable
706             * カラ?用意して true/false を指定します?
707             * こ? writable カラ?の論理積により?的にチェ?ボックスの
708             * 表示の ON/OFF が決まります?
709             * なにも設定しな??合?, ViewForm.DEFAULT_WRITABLE が設定されます?
710             *
711             * @param   rw 書込み可能(true)?不可能(false)
712             */
713            public void setDefaultRowWritable( final boolean rw ) {
714                    int size = rowHeader.size() ;
715                    DBRowHeader row ;
716                    for( int i=0; i<size; i++ ) {
717                            row = rowHeader.get( i );
718                            row.setWritable( rw );
719                    }
720            }
721    
722            /**
723             * 書き込み可能な?rowWritable == true)のチェ?ボックスに対して
724             * 初期値?選択済みにするか?非選択済みにするかを?します?
725             *
726             * @param   rw 選択状?true)?非選択状?false)
727             */
728            public void setDefaultRowChecked( final boolean rw ) {
729                    int size = rowHeader.size() ;
730                    DBRowHeader row ;
731                    for( int i=0; i<size; i++ ) {
732                            row = rowHeader.get( i );
733                            row.setChecked( rw );
734                    }
735            }
736    
737            /**
738             * 検索結果?オーバ?フローしたかど?をチェ?します?
739             * Query で検索した場合に、DB_MAX_ROW_COUNT また?、Query.setMaxRowCount( int maxRowCount )
740             * で?された値よりも検索結果が多い場合に、DBTableModel は、?の設定?までの
741             * ??タを取り込みます?そ?ときに、オーバ?フローフラグを立てておくことで、最大件数?
742             * オーバ?したかど?を判断します?
743             *
744             * @return   オーバ?フロー(true)?正常(false)
745             */
746            public boolean isOverflow() {
747                    return overflow;
748            }
749    
750            /**
751             * 検索結果?オーバ?フローしたかど?を設定します?
752             * Query で検索した場合に、DB_MAX_ROW_COUNT また?、Query.setMaxRowCount( int maxRowCount )
753             * で?された値よりも検索結果が多い場合に、DBTableModel は、?の設定?までの
754             * ??タを取り込みます?そ?ときに、オーバ?フローフラグを立てておくことで、最大件数?
755             * オーバ?したかど?を判断します?
756             *
757             * @param   of オーバ?フロー(true)?正常(false)
758             */
759            public void setOverflow( final boolean of ) {
760                    overflow = of;
761            }
762    
763            /**
764             * 検索されたDBTableModelが登録時に同?ど?を判断する為の 整合?キーを取得します?
765             *
766             * ここでの整合?は、同??ョン(ユーザー)毎にユニ?クかど?で対応します?
767             * ?環??のセ?ョン?での整合?は、確保できません?
768             * 整合?キー は、オブジェクト作?時刻としますが、?変更される可能性があります?
769             *
770             * @og.rev 3.5.5.5 (2004/04/23) 新規追?
771             *
772             * @return   整合?キー(オブジェクト?作?時刻)
773             */
774            public String getConsistencyKey() {
775                    return consistencyKey;
776            }
777    
778            /**
779             * カラ?定義されたDBTypeよりNativeタイプを返します?
780             * Nativeタイプ?org.opengion.fukurou.model.NativeTypeで定義されて?す?
781             *
782             * @og.rev 4.1.1.2 (2008/02/28) 新規追?
783             *
784             * @param  clm      値が参照される?
785             *
786             * @return Nativeタイ?
787             * @see org.opengion.fukurou.model.NativeType
788             */
789            public NativeType getNativeType( final int clm ) {
790                    return dbColumns[clm].getNativeType();
791            }
792    
793            /**
794             * カラ??にmustタイプ?を割り当てます?
795             * こ?値は、columnCheck 時? nullCheck ?mustAnyCheck の
796             * チェ?対象カラ?して認識されます?
797             *
798             * @og.rev 4.1.2.1 (2008/03/13) interface に新規登録
799             *
800             * @param   dbColumn  カラ?ブジェク?
801             * @param   type      mustタイ?must,mustAny)
802             */
803            public void addMustType( final int dbColumn, final String type ) {
804                    Set<String> set = mustMap.get( type );
805                    if( set == null ) { set = new HashSet<String>(); }
806                    set.add( names[dbColumn] );
807                    mustMap.put( type,set );
808            }
809    
810            /**
811             * mustType="must"時?カラ?を???配?として返します?
812             * こ?値は、columnCheck 時? nullCheck のチェ?対象カラ?して
813             * 認識されます?
814             * カラ?配?は、ソート済みです?
815             *
816             * @og.rev 4.1.2.1 (2008/03/13) interface に新規登録
817             *
818             * @return  mustType="must"時?カラ?配?(ソート済み)
819             */
820            public String[] getMustArray() {
821                    String[] rtn = null;
822    
823                    Set<String> set = mustMap.get( "must" );
824    //              if( set != null && set.size() > 0 ) {
825                    if( set != null && ! set.isEmpty() ) {
826                            rtn = set.toArray( new String[set.size()] );
827                            Arrays.sort( rtn );
828                    }
829                    return rtn ;
830            }
831    
832            /**
833             * mustType="mustAny" 他?カラ?を???配?として返します?
834             * こ?値は、columnCheck 時? mustAnyCheck のチェ?対象カラ?して
835             * 認識されます?
836             * カラ?配?は、ソート済みです?
837             *
838             * @og.rev 4.1.2.1 (2008/03/13) interface に新規登録
839             *
840             * @return  mustType="mustAny"時?カラ?配?(ソート済み)
841             */
842            public String[] getMustAnyArray() {
843    
844                    List<String> list = new ArrayList<String>();
845    
846                    String[] keys = mustMap.keySet().toArray( new String[mustMap.size()] );
847                    for( int i=0; i<keys.length; i++ ) {
848                            String key = keys[i];
849                            if( ! "must".equals( key ) ) {
850                                    Set<String> set = mustMap.get( key );
851    //                              if( set != null && set.size() > 0 ) {
852                                    if( set != null && !set.isEmpty() ) {
853                                            String str = StringUtil.iterator2line( set.iterator(),"|" );
854                                            list.add( str );
855                                    }
856                            }
857                    }
858    
859                    String[] rtn = null;
860    //              if( list.size() > 0 ) {
861                    if( ! list.isEmpty() ) {
862                            rtn = list.toArray( new String[list.size()] );
863                            Arrays.sort( rtn );
864                    }
865    
866                    return rtn ;
867            }
868    }