    001/*
    002 * Copyright (c) 2009 The openGion Project.
    003 *
    004 * Licensed under the Apache License, Version 2.0 (the "License");
    005 * you may not use this file except in compliance with the License.
    006 * You may obtain a copy of the License at
    007 *
    008 *     http://www.apache.org/licenses/LICENSE-2.0
    009 *
    010 * Unless required by applicable law or agreed to in writing, software
    011 * distributed under the License is distributed on an "AS IS" BASIS,
    012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
    013 * either express or implied. See the License for the specific language
    014 * governing permissions and limitations under the License.
    015 */
    016package org.opengion.plugin.io;
    017
    018import java.io.BufferedReader;
    019import java.io.IOException;
    020
    021import org.opengion.fukurou.util.StringUtil;
    022import org.opengion.hayabusa.common.HybsSystem;
    023import org.opengion.hayabusa.common.HybsSystemException;
    024import org.opengion.hayabusa.db.DBTableModelUtil;
    025import org.opengion.hayabusa.io.AbstractTableReader;
    026
    027/**
    028 * 指定の区切り記号(初期値:タブ区切り)ファイルの読み取りクラスです。
    029 *
    030 * 名前，データの入力部のみオーバーライドすれば，各種入力フォーマットに合わせた
    031 * サブクラスを実現する事が可能です。
    032 *
    033 * @og.group ファイル入力
    034 *
    035 * @version  4.0
    036 * @author   Kazuhiko Hasegawa
    037 * @since    JDK5.0,
    038 */
    039public class TableReader_Default extends AbstractTableReader {
    040        //* このプログラムのVERSION文字列を設定します。   {@value} */
    041        private static final String VERSION = "5.2.1.0 (2010/10/01)" ;
    042
    043        /**
    044         * DBTableModel から 各形式のデータを作成して,BufferedReader より読み取ります。
    045         * コメント/空行を除き、最初の行は、必ず項目名が必要です。
    046         * それ以降は、コメント/空行を除き、データとして読み込んでいきます。
    047         * このメソッドは、EXCEL 読み込み時に使用します。
    048         *
    049         * @og.rev 4.0.0.0 (2006/09/31) 新規追加
    050         * @see #isExcel()
    051         */
    052        @Override
    053        public void readDBTable() {
    054                String errMsg = "このクラスでは実装されていません。";
    055                throw new UnsupportedOperationException( errMsg );
    056        }
    057
    058        /**
    059         * DBTableModel から 各形式のデータを作成して,BufferedReader より読み取ります。
    060         * コメント/空行を除き、最初の行は、必ず項目名が必要です。
    061         * それ以降は、コメント/空行を除き、データとして読み込んでいきます。
    062         *
    063         * @og.rev 3.1.1.0 (2003/03/28) 同期メソッド(synchronized付き)を非同期に変更する。
    064         * @og.rev 3.5.4.2 (2003/12/15) writer の null チェックを廃止します。
    065         * @og.rev 3.5.4.3 (2004/01/05) 引数に、BufferedReader を受け取ル要に変更します。
    066         * @og.rev 3.5.4.5 (2004/01/23) カラム名の外部指定を優先して使用する。
    067         * @og.rev 5.1.6.0 (2010/05/01) readDBTableのエラーチェック強化
    068         * @og.rev 5.1.6.0 (2010/05/01) skipRowCountの追加
    069         * @og.rev 5.2.0.0 (2010/09/01) ""で囲われているデータに改行が入っていた場合の対応
    070         * @og.rev 5.2.1.0 (2010/10/01) AbstractTableReader.java と重複している箇所の対応
    071         * @og.rev 5.9.8.1 (2016/05/13) match対応
    072         *
    073         * @param   reader BufferedReaderオブジェクト
    074         */
    075        @Override
    076        public void readDBTable( final BufferedReader reader ) {
    077                try {
    078                        String line;
    079                        String[] names = null;
    080                        int numberOfRows = 0;
    081//                      char  sepa = separator.charAt( 0 );
    082                        char  sepa = getSeparator().charAt( 0 );        // 5.2.0.0 (2010/09/01)
    083
    084                        boolean nameNoSet = true;
    085                        table = DBTableModelUtil.newDBTable();
    086
    087                        // 3.5.4.5 (2004/01/23) カラム名の外部指定を優先して使用する。
    088                        if( columns != null && columns.length() > 0 ) {
    089                                names = StringUtil.csv2Array( columns );
    090                                table.init( names.length );
    091                                setTableDBColumn( names ) ;
    092                                nameNoSet = false;
    093                        }
    094
    095//                      int skip = skipRowCount;                                                // 5.1.6.0 (2010/05/01)
    096                        int skip = getSkipRowCount();                                   // 5.2.0.0 (2010/09/01)
    097                        String[] readData;      // 5.9.8.1 (2016/05/13)
    098                        while((line = reader.readLine()) != null) {
    099                                // 5.2.0.0 (2010/09/01) ""で囲われているデータに改行が入っていた場合の対応
    100//                              int quotCount = StringUtil.countChar( line, '"' );
    101//                              if( quotCount % 2 == 1 ) {
    102//                                      String addLine = null;
    103//                                      while(quotCount % 2 == 1 && (addLine = reader.readLine()) != null) {
    104//                                              line +=  HybsSystem.CR + addLine;
    105//                                              quotCount += StringUtil.countChar( addLine, '"' );
    106//                                      }
    107//                              }
    108                                // 5.2.1.0 (2010/10/01) findbugs 対策(文字列の + 連結と、奇数判定ロジック)
    109                                int quotCount = StringUtil.countChar( line, '"' );
    110                                if( quotCount % 2 != 0 ) {
    111                                        String addLine = null;
    112                                        StringBuilder buf = new StringBuilder( line );
    113                                        while(quotCount % 2 != 0 && (addLine = reader.readLine()) != null) {
    114                                                buf.append( HybsSystem.CR ).append( addLine );
    115                                                quotCount += StringUtil.countChar( addLine, '"' );
    116                                        }
    117                                        line = buf.toString();
    118                                }
    119
    120                                if( skip > 0 ) { skip--; continue; }         // 5.1.6.0 (2010/05/01)
    121                                if( line.length() == 0 ) { continue; }
    122                                if( line.charAt( 0 ) == '#' ) {
    123                                        String key = line.substring( 0,5 );
    124                                        if( nameNoSet && ( key.equalsIgnoreCase( "#NAME" ) )) {
    125                                                // 超イレギュラー処理 最初の TAB_SEPARATOR 以前の文字は無視する。
    126                                                String line2 = line.substring( line.indexOf( sepa )+1 );
    127                                                names = StringUtil.csv2Array( line2 ,sepa );
    128                                                table.init( names.length );
    129                                                setTableDBColumn( names ) ;
    130                                                nameNoSet = false;
    131                                        }
    132                                        else  { continue; }
    133                                }
    134                                else {
    135                                        if( nameNoSet ) {
    136                                                String errMsg = "#NAME が見つかる前にデータが見つかりました。";
    137                                                throw new HybsSystemException( errMsg );
    138                                        }
    139                                        if( numberOfRows < getMaxRowCount() ) {
    140//                                              setTableColumnValues( readData( line,names.length ) );          // 5.2.1.0 (2010/10/01)
    141//                                              table.addColumnValues( readData( line,names.length ) );
    142
    143                                                // 5.9.8.1 (2016/05/13) match対応
    144                                                readData = readData( line,names.length );
    145                                                if( matchCheck( readData, names ) ){
    146                                                        setTableColumnValues( readData );
    147                                                        numberOfRows ++ ;
    148                                                }
    149                                        }
    150                                        else {
    151                                                table.setOverflow( true );
    152                                        }
    153                                }
    154                        }
    155
    156                        // 5.1.6.0 (2010/05/01) readDBTableのエラーチェック強化
    157                        if( nameNoSet ) {
    158                                String errMsg = "ファイルから有効なデータが見つかりませんでした。";
    159                                throw new HybsSystemException( errMsg );
    160                        }
    161                }
    162                catch ( IOException ex ) {
    163                        String errMsg = "ファイル読込みエラー[" + reader + "]"  ;
    164                        throw new HybsSystemException( errMsg,ex );             // 3.5.5.4 (2004/04/15) 引数の並び順変更
    165                }
    166        }
    167}