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    }