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 java.math.BigDecimal;
019    import java.sql.ResultSet;
020    import java.sql.ResultSetMetaData;
021    import java.sql.SQLException;
022    import java.text.DecimalFormat;
023    import java.util.ArrayList;
024    import java.util.HashMap;
025    import java.util.LinkedHashMap;
026    import java.util.List;
027    import java.util.Locale;
028    import java.util.Map;
029    
030    import org.opengion.fukurou.db.DBUtil;
031    import org.opengion.fukurou.util.StringUtil;
032    import org.opengion.hayabusa.common.HybsSystem;
033    import org.opengion.hayabusa.common.HybsSystemException;
034    import org.opengion.hayabusa.resource.LabelData;
035    import org.opengion.hayabusa.resource.ResourceManager;
036    
037    /**
038     * DBTableModelを継承した TableModelの編?定による変換を行うための実?ラスです?
039     *
040     * こ?クラスでは、オブジェクト?期化後???常のDBTableModelと同じ振る??します?
041     * オブジェクト?期化?createメソ?呼び出し時)に、検索結果オブジェクトから直接、編?定に
042     * 応じて変換されたDBTableModelを生成します?
043     *
044     * こ?ような実?行う?は、メモリ使用量を??るためです?
045     * こ?編?定では?計機?を備えて?すが、?DBTableModel作?後に???行うと?
046     * メモリを大量に使用する恐れがあるため?検索結果オブジェクトから直接???行い、DBTableModel?
047     * 生?して?す?
048     *
049     * DBTableModel インターフェースは?データベ?スの検索結果(Resultset)をラ??する
050     * インターフェースとして使用して下さ??
051     *
052     * @og.rev 5.3.6.0 (2011/06/01) 新規作?
053     * @og.group ??ブル管?
054     *
055     * @version  5.0
056     * @author   Hiroki Nakamura
057     * @since    JDK6.0,
058     */
059    public class DBTableModelEditor extends DBTableModelImpl {
060            private static final String JS                          = HybsSystem.JOINT_STRING;
061            private static final DecimalFormat FORMAT       = new DecimalFormat( "0.#########" );
062    
063            private int rowCountColumn = -1;
064            private DBEditConfig config;
065    
066            /**
067             * DBTableModel を設定し、このオブジェクトを初期化します?
068             *
069             * @og.rev 5.7.1.2 (2013/12/20) msg ?errMsg 変更
070             * @og.rev 5.8.2.0 (2014/12/05) 合計時のエラーチェ?追?
071             *
072             * @param       result                  検索結果オブジェク?
073             * @param       skipRowCount    読み飛?し件数
074             * @param       maxRowCount             ?検索件数
075             * @param       resource                ResourceManagerオブジェク?
076             * @param       config                  エ??設定オブジェク?
077             * @throws      SQLException ??タベ?スアクセスエラー
078             */
079            public void create( final ResultSet result, final int skipRowCount, final int maxRowCount, final ResourceManager resource, final DBEditConfig config ) throws SQLException {
080                    if( result == null || config == null || resource == null ) {
081    //                      String msg = "DBTableModelまた?、DBEditConfigが設定されて?せん?;
082    //                      throw new HybsSystemException( msg );
083                            String errMsg = "DBTableModelまた?、DBEditConfigが設定されて?せん?;
084                            throw new HybsSystemException( errMsg );        // 5.7.1.2 (2013/12/20) msg ?errMsg 変更
085                    }
086    
087                    this.config = config;
088    
089                    /**********************************************************************
090                     * ?ラメーターの初期化??
091                     **********************************************************************/
092                    ResultSetMetaData metaData      = result.getMetaData();
093                    int colCnt = metaData.getColumnCount();
094                    if( config.useGroup() || config.useSubTotal() || config.useTotal() || config.useGrandTotal() ) {
095                            rowCountColumn = colCnt;
096                            colCnt++;
097                    }
098                    init( colCnt );
099    
100                    DBColumn[] dbColumn = new DBColumn[numberOfColumns];
101                    int[] types  = new int[numberOfColumns];
102                    boolean[] sumFilter = new boolean[numberOfColumns];
103                    boolean[] groupFilter = new boolean[numberOfColumns];
104                    boolean[] subTotalFilter = new boolean[numberOfColumns];
105                    boolean[] totalFilter = new boolean[numberOfColumns];
106                    boolean   sumFilterCheck        = false; // 5.8.2.0 (2014/12/05)
107                    for( int column=0; column<numberOfColumns; column++ ) {
108                            String name = null;
109                            if( column != rowCountColumn ) {
110                                    name = (metaData.getColumnLabel(column+1)).toUpperCase(Locale.JAPAN);
111                                    types[column] = metaData.getColumnType(column+1);
112                                    dbColumn[column] = resource.getDBColumn( name );
113                                    if( dbColumn[column] == null ) {
114                                            LabelData labelData  = resource.getLabelData( name );
115                                            dbColumn[column] = DBTableModelUtil.makeDBColumn( name,labelData,metaData,column,resource.getLang() );
116                                    }
117                            }
118                            else {
119                                    name = "rowCount";
120                                    dbColumn[column] = resource.makeDBColumn( name );
121                            }
122    
123                            setDBColumn( column,dbColumn[column] );
124    
125                            sumFilter[column] = config.isSumClm( name );
126                            groupFilter[column] = config.isGroupClm( name );
127                            subTotalFilter[column] = config.isSubTotalClm( name );
128                            totalFilter[column] = config.isTotalClm( name );
129                            
130                            //5.8.2.0 (2014/12/05) チェ?追?
131                            if( sumFilter[column] || groupFilter[column] || subTotalFilter[column] || totalFilter[column] ) {
132                                    sumFilterCheck = true;
133                            }
134                    }
135    
136                    /**********************************************************************
137                     * ??ソート?合計??
138                     **********************************************************************/
139                    // ?キーに基づく集計??行い??タを追?ます?
140                    if( config.useGroup() ) {
141                            addGroupRows( result, types, skipRowCount, maxRowCount, sumFilter, groupFilter  );
142                    }
143                    // 通常と同じように結果カーソルから??タを読込み??タを追?ます?
144                    else {
145                            // 5.5.2.4 (2012/05/16) int[] types は使われて???で、削除します?
146    //                      addPlainRows( result, types, skipRowCount, maxRowCount );
147                            addPlainRows( result, skipRowCount, maxRowCount );
148                    }
149    
150                    // ソート??
151                    if( getRowCount() > 0 && config.useOrderBy() ) {
152                            sort();
153                    }
154    
155                    // 小計?合計行を追?ます?
156                    if( getRowCount() > 0 && !isOverflow()
157                            && ( config.useSubTotal() || config.useTotal() || config.useGrandTotal() ) ) {
158                            
159                            // 5.8.2.0 (2014/12/05) queryタグが?あり、mainTrans=false で制御されて???合?エラーが発生す?
160                            if( !sumFilterCheck ) {
161                                    String errMsg = "小計?合計カラ?存在しません?
162                                                                    + " これは、queryタグが?あり、mainTrans=false で制御されて??能性があります?" ;
163                                    throw new HybsSystemException( errMsg );
164                            }
165                            
166                            addTotalRows( maxRowCount, resource, sumFilter, groupFilter, subTotalFilter, totalFilter );
167                    }
168            }
169    
170            /**
171             * ?キーの設定に基づき?DBTableModelの行を追?ます?
172             * ??は、キーブレイクではなく??マップにより???行って?ため?
173             * ?キーが検索?より散在した場合で?まとまりで?されます?
174             *
175             * @og.rev 5.3.9.0 (2011/09/01) 値がNULLの場合にエラーになるバグを修正
176             * @og.rev 5.6.1.0 (2013/02/01) doubleをBigDecimalに
177             *
178             * @param result 検索結果オブジェク?
179             * @param types カラ?イプ?配?
180             * @param skipRowCount 読み飛?し件数
181             * @param maxRowCount ?検索件数
182             * @param sumFilter ??目フィルター
183             * @param groupFilter グループキーフィルター
184             * @throws SQLException ??タベ?スアクセスエラー
185             */
186            private void addGroupRows( final ResultSet result, final int[] types, final int skipRowCount, final int maxRowCount
187                                                                    , final boolean[] sumFilter, final boolean[] groupFilter ) throws SQLException {
188                    int numberOfRows = 0;
189                    while( numberOfRows < skipRowCount && result.next() ) {
190                            // 注?resultSet.next() を?に判定すると??件読み飛?してしま??
191                            numberOfRows ++ ;
192                    }
193                    numberOfRows = 0;
194    
195                    Map<String,String[]> groupLinkedMap = new LinkedHashMap<String,String[]>();
196                    Map<String,Integer> groupCountMap = new HashMap<String,Integer>();
197    //              Map<String,double[]> sumMap = new HashMap<String,double[]>();
198                    Map<String,BigDecimal[]> sumMap = new HashMap<String,BigDecimal[]>(); // 5.6.1.0 (2013/02/01)
199                    while( numberOfRows < maxRowCount && result.next() ) {
200                            StringBuilder groupKey = new StringBuilder();
201    //                      double[] sumVals = new double[config.getSumClmCount()];
202                            BigDecimal[] sumVals = new BigDecimal[config.getSumClmCount()]; // 5.6.1.0 (2013/02/01) 
203                            String[] groupVals = new String[config.getGroupClmCount()];
204                            int sc = 0;
205                            int gc = 0;
206                            for( int column=0; column<numberOfColumns; column++ ) {
207                                    if( column != rowCountColumn ) {
208                                            String val = DBUtil.getValue( result, column, types[column] );
209                                            if( sumFilter[column] ) {
210                                                    // 5.3.9.0 (2011/09/01) 値がNULLの場合?対応漏れ
211    //                                              sumVals[sc++] = Double.valueOf( val );
212                                                    // sumVals[sc++] = ( val != null && val.length() > 0 ? Double.valueOf( val ) : 0 );
213                                                    sumVals[sc++] = ( val != null && val.length() > 0 ? new BigDecimal( val ) : new BigDecimal(0) ); // 5.6.1.0 (2013/02/01)
214                                            }
215                                            if( groupFilter[column] ) {
216                                                    groupVals[gc++] = val;
217                                                    groupKey.append( val ).append( JS );
218                                            }
219                                    }
220                            }
221    
222                            String key = groupKey.toString();
223                            int groupCount = 0;
224                            if( groupLinkedMap.containsKey( key ) ) {
225    //                              double[] eSumVals = sumMap.get( key );
226                                    BigDecimal[] eSumVals = sumMap.get( key ); // 5.6.1.0 (2013/02/01)
227                                    for( int i=0; i<config.getSumClmCount(); i++ ) {
228    //                                      sumVals[i] += eSumVals[i];
229                                            sumVals[i] = sumVals[i] == null ? new BigDecimal(0) : sumVals[i].add( eSumVals[i] ); // 5.6.1.0 (2013/02/01)
230                                    }
231                                    sumMap.put( key, sumVals );
232                                    groupCount = groupCountMap.get( key ).intValue() + 1;
233                            }
234                            else {
235                                    groupLinkedMap.put( key, groupVals );
236                                    groupCount = 1;
237                                    numberOfRows++;
238                            }
239                            sumMap.put( key, sumVals );
240                            groupCountMap.put( key, Integer.valueOf( groupCount ) );
241                    }
242    
243                    for( Map.Entry<String, String[]> entry : groupLinkedMap.entrySet() ) {
244                            String key = entry.getKey();
245                            addRow( groupFilter, entry.getValue(), groupCountMap.get( key ), sumFilter, sumMap.get( key ) );
246                    }
247    
248                    // ?件数が??た?合でかつ次の??タがある?合?、オーバ?フロー
249                    if( numberOfRows >= maxRowCount && result.next() ) {
250                            setOverflow( true );
251                    }
252            }
253    
254            /**
255             * 検索結果オブジェクトを?読み取り、そのままDBTableModelの行を追?ます?
256             *
257             * @og.rev 5.5.2.4 (2012/05/16) int[] types は使われて???で、削除します?
258             *
259             * @param result 検索結果オブジェク?
260             * @param skipRowCount 読み飛?し件数
261             * @param maxRowCount ?検索件数
262             * @throws      SQLException ??タベ?スアクセスエラー
263             */
264    //      private void addPlainRows( final ResultSet result, final int[] types, final int skipRowCount, final int maxRowCount ) throws SQLException {
265            private void addPlainRows( final ResultSet result, final int skipRowCount, final int maxRowCount ) throws SQLException {
266                    int numberOfRows = 0;
267                    while( numberOfRows < skipRowCount && result.next() ) {
268                            // 注?resultSet.next() を?に判定すると??件読み飛?してしま??
269                            numberOfRows ++ ;
270                    }
271                    numberOfRows = 0;
272    
273                    while( numberOfRows < maxRowCount && result.next() ) {
274                            numberOfRows++ ;
275                            String[] columnValues = new String[numberOfColumns];
276                            for( int column=0; column<numberOfColumns; column++ ) {
277                                    if( column != rowCountColumn ) {
278                                            Object obj = result.getObject(column+1);
279                                            columnValues[column] = ( obj == null ? "" : String.valueOf( obj ) );
280                                    }
281                                    else {
282                                            columnValues[column] = "";
283                                    }
284                            }
285                            addColumnValues( columnValues );
286                    }
287    
288                    // ?件数が??た?合でかつ次の??タがある?合?、オーバ?フロー
289                    if( numberOfRows >= maxRowCount && result.next() ) {
290                            setOverflow( true );
291                    }
292            }
293    
294            /**
295             * DBTableModelのソート??行います?
296             *
297             */
298            private void sort() {
299                    // orderByClmsによる並び替?
300                    DBTableModelSorter temp = new DBTableModelSorter();
301                    temp.setModel( this );
302                    String[] oClms = StringUtil.csv2Array( config.getOrderByClms() );
303                    for( int i=oClms.length-1; i>=0; i-- ) {
304                            String oc = oClms[i];
305                            boolean ascending = true;
306                            if( oc.startsWith( "!" ) ) {
307                                    oc = oc.substring( 1 );
308                                    ascending = false;
309                            }
310                            int clmNo = getColumnNo( oc );
311                            temp.sortByColumn( clmNo, ascending );
312                    }
313                    this.data = temp.data;
314                    this.rowHeader = temp.rowHeader;
315            }
316    
317            /**
318             * DBTableModelから??タを読み取り、エ??設定情報を?に合計行?追???行います?
319             * 合計行?追??、キーブレイクにより行われます?で、同じキーが?回?現した場合??
320             * それぞれの行に対して、合計行が付加されます?
321             *
322             * @og.rev 5.3.7.0 (2011/07/01) 小計?合計行追???オーバ?フローフラグがセ?されな?グを修正
323             * @og.rev 5.6.1.0 (2013/02/01) 誤差回避のため、doubleではなくdecimalで計算す?
324             * @og.rev 5.6.8.1 (2013/09/13) 1行目が合計されて?かった?で修正
325             * @og.rev 5.8.2.0 (2014/12/05) エラー対?
326             *
327             * @param       maxRowCount ?検索件数
328             * @param       resource リソースマネージャー
329             * @param       sumFilter ??目フィルター
330             * @param       groupFilter グループキーフィルター
331             * @param       subTotalFilter 小計キーフィルター
332             * @param       totalFilter 合計キーフィルター
333             *
334             * @return      オーバ?フローしたかど?(?件数が?た?合でかつ次の??タがある?合?、true)
335             */
336            private boolean addTotalRows( final int maxRowCount, final ResourceManager resource, final boolean[] sumFilter
337                                                                            ,  final boolean[] groupFilter, final boolean[] subTotalFilter,  final boolean[] totalFilter ) {
338    
339                    String subTotalLabel = ( config.useSubTotal() ? resource.makeDBColumn( "EDIT_SUBTOTAL_VALUE" ).getLongLabel() : null );
340                    String totalLabel = ( config.useTotal() ? resource.makeDBColumn( "EDIT_TOTAL_VALUE" ).getLongLabel() : null );
341                    String grandTotalLabel = ( config.useGrandTotal() ? resource.makeDBColumn( "EDIT_GRANDTOTAL_VALUE" ).getLongLabel() : null );
342    
343                    int numberOfRows = getRowCount();
344                    int sumClmCount = config.getSumClmCount();
345    //              double subTotalSum[] = new double[sumClmCount];
346    //              double totalSum[] = new double[sumClmCount];
347    //              double grandTotalSum[] = new double[sumClmCount];
348                    BigDecimal subTotalSum[] = new BigDecimal[sumClmCount]; // 5.6.1.0 (2013/02/01)
349                    BigDecimal totalSum[] = new BigDecimal[sumClmCount];
350                    BigDecimal grandTotalSum[] = new BigDecimal[sumClmCount];
351    
352                    String lastSubTotalKey = null;
353                    String lastTotalKey = null;
354    
355                    int subTotalCount = 0;
356                    int totalCount = 0;
357                    int grandTotalCount = 0;
358                    int rowCount =0;
359    
360                    int tblIdx = 0;
361                    while( numberOfRows < maxRowCount && tblIdx < getRowCount() ) {
362    //                      double[] sumVals = new double[sumClmCount];
363                            BigDecimal[] sumVals = new BigDecimal[sumClmCount]; // 5.6.1.0 (2013/02/01)
364                            StringBuilder groupKey = new StringBuilder();
365                            StringBuilder subTotalKey = new StringBuilder();
366                            StringBuilder totalKey = new StringBuilder();
367    
368                            int sc = 0;
369                            for( int column=0; column<numberOfColumns; column++ ) {
370                                    String val = getValue( tblIdx, column );
371                                    if( groupFilter[column] )               { groupKey.append( val ).append( JS ); }
372    //                              if( sumFilter[column] )                 { sumVals[sc++] = ( val != null && val.length() > 0 ? Double.valueOf( val ) : 0 ); }
373                                    if( sumFilter[column] )                 { sumVals[sc++] = ( val != null && val.length() > 0 ? new BigDecimal( val ) : new BigDecimal(0) ); } // 5.6.1.0 (2013/02/01)
374                                    if( subTotalFilter[column] )    { subTotalKey.append( val ).append( JS ); }
375                                    if( totalFilter[column] )               { totalKey.append( val ).append( JS ); }
376    //                              if( column == rowCountColumn )  { rowCount = ( val != null && val.length() > 0 ? Integer.valueOf( val ) : 0 ); }
377                                    if( column == rowCountColumn )  { rowCount = ( val != null && val.length() > 0 ? Integer.parseInt( val ) : 0 ); } // 5.8.2.0 (2014/12/05) メソ?変更
378                            }
379    
380                            // 小計キーブレイク処?
381                            if( numberOfRows < maxRowCount && config.useSubTotal() && lastSubTotalKey != null && lastSubTotalKey.length() > 0
382                                    && !lastSubTotalKey.equals( subTotalKey.toString() ) ) {
383                                    addRow( subTotalFilter, subTotalLabel, subTotalCount, sumFilter, subTotalSum, tblIdx );
384    //                              subTotalSum = new double[sumClmCount];
385                                    subTotalSum = new BigDecimal[sumClmCount]; // 5.6.1.0 (2013/02/01)
386                                    subTotalCount = 0;
387                                    numberOfRows++;
388                                    tblIdx++;
389                            }
390    
391                            // 合計キーブレイク処?
392                            if( numberOfRows < maxRowCount && config.useTotal() && lastTotalKey != null && lastTotalKey.length() > 0
393                                    && !lastTotalKey.equals( totalKey.toString() ) ) {
394                                    addRow( totalFilter, totalLabel, totalCount, sumFilter, totalSum, tblIdx );
395    //                              totalSum = new double[sumClmCount];
396                                    totalSum = new BigDecimal[sumClmCount]; // 5.6.1.0 (2013/02/01)
397                                    totalCount = 0;
398                                    numberOfRows++;
399                                    tblIdx++;
400                            }
401    
402                            // 小計?合計?総合計単位に??目の合計?を加算します?
403                            // 6.0.2.0 (2014/09/19) BigDecimal.ZERO.add で、null エラーが発生する?は、query が?あり、mainTrans=false で制御されて????
404    //                      for( int cnt=0; cnt<sumClmCount; cnt++ ) {
405                            for( int cnt=0; cnt<sc; cnt++ ) {
406                                    subTotalSum[cnt] = subTotalSum[cnt] == null ? new BigDecimal(0).add(sumVals[cnt]) : subTotalSum[cnt].add(sumVals[cnt]); // 5.6.8.1 (2013/09/13)
407                                    totalSum[cnt] = totalSum[cnt] == null ? new BigDecimal(0).add(sumVals[cnt]) : totalSum[cnt].add(sumVals[cnt]);
408                                    grandTotalSum[cnt] = grandTotalSum[cnt] == null ? new BigDecimal(0).add(sumVals[cnt]) : grandTotalSum[cnt].add(sumVals[cnt]);
409    
410                            }
411    
412                            lastSubTotalKey = subTotalKey.toString();
413                            lastTotalKey = totalKey.toString();
414    
415                            // グループ集計時はグルーピングした行数を加算する?
416                            int gcnt = 1;
417                            if( config.useGroup() && rowCountColumn >= 0 && rowCount > 0 ) {
418                                    gcnt = rowCount;
419                            }
420                            subTotalCount += gcnt;
421                            totalCount    += gcnt;
422                            grandTotalCount += gcnt;
423    
424                            tblIdx++;
425                    }
426    
427                    // ?件数が??た?合でかつ次の??タがある?合?、オーバ?フロー
428                    boolean isOverFlow = ( tblIdx < getRowCount() );
429    
430                    // 小計キー?行??
431                    if( config.useSubTotal() && lastSubTotalKey != null ) {
432                            if( numberOfRows < maxRowCount ) {
433                                    addRow( subTotalFilter, subTotalLabel, subTotalCount, sumFilter, subTotalSum, tblIdx );
434                                    numberOfRows++;
435                                    tblIdx++;
436                            }
437                            else {
438                                    isOverFlow = true;
439                            }
440                    }
441    
442                    // 合計キー?行??
443                    if( config.useTotal() && lastTotalKey != null ) {
444                            if( numberOfRows < maxRowCount ) {
445                                    addRow( totalFilter, totalLabel, totalCount, sumFilter, totalSum, tblIdx );
446                                    numberOfRows++;
447                                    tblIdx++;
448                            }
449                            else {
450                                    isOverFlow = true;
451                            }
452                    }
453    
454                    // 総合計??
455                    if( config.useGrandTotal() && numberOfRows > 0 ) {
456                            if( numberOfRows < maxRowCount ) {
457                                    boolean[] grandTotalFilter = new boolean[numberOfColumns];
458                                    // 総合計?ラベル表示?
459                                    // grandTotalFilter[0] = true;
460                                    addRow( grandTotalFilter, grandTotalLabel, grandTotalCount, sumFilter, grandTotalSum, tblIdx );
461                                    numberOfRows++;
462                                    tblIdx++;
463                            }
464                            else {
465                                    isOverFlow = true;
466                            }
467                    }
468    
469                    if( isOverFlow ) {
470                            setOverflow( true );
471                    }
472    
473                    return isOverFlow;
474            }
475    
476            /**
477             * キーの値配??計?の配?を引数として、追?を生?し?DBTableModelに追?ます?
478             * キー、及び??がDBTableModel上?どのカラ?位置するか?、キーフィルタ?計フィルタで?します?
479             * 
480             * @og.rev 5.6.1.0 (2013/02/01) doubleをdecimalに
481             *
482             * @param keyFilter キーフィルタ
483             * @param keyVals キーの値配?
484             * @param keyCount ?した行?カウン?
485             * @param sumFilter ?フィルタ
486             * @param sumVals ??配?
487             * @param aRow 挿入する行番号
488             */
489    //      private void addRow( final boolean[] keyFilter, final String[] keyVals, final int keyCount
490    //                                                      , final boolean[] sumFilter, final double[] sumVals, final int aRow ) {
491            private void addRow( final boolean[] keyFilter, final String[] keyVals, final int keyCount
492                            , final boolean[] sumFilter, final BigDecimal[] sumVals, final int aRow ) {
493                    String[] columnValues = new String[numberOfColumns];
494                    int sc = 0;
495                    int kc = 0;
496                    for( int column=0; column<numberOfColumns; column++ ) {
497                            String val = "";
498                            if( keyFilter[column] ) {
499                                    val = keyVals[kc++];
500                            }
501                            if( sumFilter[column] ) {
502                                    val = FORMAT.format( sumVals[sc++] );
503                            }
504                            if( column == rowCountColumn ) {
505                                    val = String.valueOf( keyCount );
506                            }
507                            columnValues[column] = val;
508                    }
509    
510                    if( aRow < 0 ) {
511                            addColumnValues( columnValues );
512                    }
513                    else {
514                            addValues( columnValues, aRow, false );
515                    }
516            }
517    
518            /**
519             * キーの値配??計?の配?を引数として、追?を生?し?DBTableModelに追?ます?
520             * キー、及び??がDBTableModel上?どのカラ?位置するか?、キーフィルタ?計フィルタで?します?
521             * 
522             * @og.rev 5.6.1.0 (2013/02/01) doubleをbigDecimal
523             *
524             * @param keyFilter キーフィルタ
525             * @param keyVals キーの値配?
526             * @param keyCount ?した行?カウン?
527             * @param sumFilter ?フィルタ
528             * @param sumVals ??配?
529             */
530    //      private void addRow( final boolean[] keyFilter, final String[] keyVals, final int keyCount
531    //                                                      , final boolean[] sumFilter, final double[] sumVals ) {
532            private void addRow( final boolean[] keyFilter, final String[] keyVals, final int keyCount
533                            , final boolean[] sumFilter, final BigDecimal[] sumVals ) {
534                    addRow( keyFilter, keyVals, keyCount, sumFilter, sumVals, -1 );
535            }
536    
537            /**
538             * キーの値?計?の配?を引数として、追?を生?し?DBTableModelに追?ます?
539             * キー、及び??がDBTableModel上?どのカラ?位置するか?、キーフィルタ?計フィルタで?します?
540             * 
541             * @og.rev 5.6.1.0 (2013/02/01) doubleをbigDecimalに
542             *
543             * @param keyFilter キーフィルタ
544             * @param keyVal キーの値
545             * @param keyCount ?した行?カウン?
546             * @param sumFilter ?フィルタ
547             * @param sumVals ??配?
548             * @param aRow 挿入する行番号
549             */
550    //      private void addRow( final boolean[] keyFilter, final String keyVal, final int keyCount
551    //                                                      , final boolean[] sumFilter, final double[] sumVals, final int aRow ) {
552            private void addRow( final boolean[] keyFilter, final String keyVal, final int keyCount
553                            , final boolean[] sumFilter, final BigDecimal[] sumVals, final int aRow ) {
554                    List<String> tmp = new ArrayList<String>();
555                    for( int column=0; column<numberOfColumns; column++ ) {
556                            if( keyFilter[column] ) {
557                                    tmp.add( keyVal );
558                            }
559                    }
560    //              addRow( keyFilter, tmp.toArray( new String[0] ), keyCount, sumFilter, sumVals, aRow );
561                    addRow( keyFilter, tmp.toArray( new String[tmp.size()] ), keyCount, sumFilter, sumVals, aRow );
562            }
563    }