    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.fukurou.model;
    017
    018import java.io.BufferedReader;
    019import java.io.File;
    020import java.io.IOException;
    021import java.nio.charset.CharacterCodingException;                                       // 6.3.1.0 (2015/06/28)
    022
    023import org.opengion.fukurou.util.StringUtil;
    024import org.opengion.fukurou.util.FileUtil;
    025import org.opengion.fukurou.util.Closer;                                                // 6.2.0.0 (2015/02/27)
    026import static org.opengion.fukurou.util.HybsConst.CR;
    027import static org.opengion.fukurou.util.HybsConst.BUFFER_MIDDLE;
    028
    029/**
    030 * 指定の区切り記号(初期値:タブ区切り)ファイルの読み取りクラスです。
    031 *
    032 * txt形式のテキストファイルを、イベント方式でテキストデータを読み取ります。
    033 * タブ区切りテキストファイルで、セパレータと文字コードを外部から指定できます。
    034 *
    035 * @og.rev 6.2.0.0 (2015/02/27) 新規追加
    036 * @og.group ファイル入力
    037 *
    038 * @version  6.0
    039 * @author   Kazuhiko Hasegawa
    040 * @since    JDK6.0,
    041 */
    042public class EventReader_TEXT implements EventReader {
    043        /** このプログラムのVERSION文字列を設定します。   {@value} */
    044        private static final String VERSION = "6.3.1.0 (2015/06/28)" ;
    045
    046        private String  separator       = "\t";                 // 項目区切り文字
    047        private String  encode          = "UTF-8";              // Shift_JIS,MS932,Windows-31J,UTF-8,ISO-8859-1,UnicodeLittle･･･
    048
    049        /**
    050         * 引数ファイル(Text)を、イベントモデルを使用してテキスト化します。
    051         *
    052         * TableModelHelperは、EXCEL/TEXT読み取り処理用の統一されたイベント処理クラスです。
    053         * openGion特有のEXCEL/TEXT処理方法(#NAME , 先頭行#コメントなど)を実装しています。
    054         * これは、EXCELやTEXTの処理を、統一的なイベントモデルで扱うためです。
    055         * あくまで、読み取り限定であれば、こちらのイベントモデルで十分です。
    056         *
    057         * @og.rev 6.2.0.0 (2015/02/27) 新規作成
    058         * @og.rev 6.3.1.0 (2015/06/28) nioを使用すると UTF-8とShuft-JISで、エラーになる。
    059         *
    060         * @param       file 入力ファイル
    061         * @param       helper イベント処理するオブジェクト
    062         */
    063        @Override
    064        public void eventReader( final File file , final TableModelHelper helper ) {
    065                BufferedReader  reader  = null ;
    066
    067                try {
    068                        helper.startFile( file );
    069
    070                        // 6.2.0.0 (2015/02/27) TableModelHelper 変更に伴う修正
    071                        reader = FileUtil.getBufferedReader( file,encode );
    072
    073                        String line;
    074                        int rowNo = 0;
    075                        final char sepa = separator.charAt(0);
    076
    077                        final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE );
    078                        while((line = reader.readLine()) != null) {
    079                                if( helper.isSkip( rowNo ) ) { break; }
    080
    081                                // 5.2.0.0 (2010/09/01) ""で囲われているデータに改行が入っていた場合の対応
    082                                int quotCount = StringUtil.countChar( line, '"' );
    083                                if( quotCount % 2 != 0 ) {
    084                                        String addLine = null;
    085                                        buf.setLength(0);
    086                                        buf.append( line );
    087                                        while(quotCount % 2 != 0 && (addLine = reader.readLine()) != null) {
    088                                                buf.append( CR ).append( addLine );
    089                                                quotCount += StringUtil.countChar( addLine, '"' );
    090                                        }
    091                                        line = buf.toString();
    092                                }
    093                                helper.value( line, rowNo++, sepa );
    094                                // オーバーフロー時は、HybsOverflowException が throw される。
    095        //                      if( helper.isOverflow() ) { break; }            // オーバーフローで打ち切り
    096                        }
    097                }
    098                // 6.3.1.0 (2015/06/28) nioを使用すると UTF-8とShuft-JISで、エラーになる。
    099                catch ( CharacterCodingException ex ) {
    100                        final String errMsg = "文字のエンコード・エラーが発生しました。" + CR
    101                                                                +       "  ファイルのエンコードが指定のエンコードと異なります。" + CR
    102                                                                +       " [" + file.getPath() + "] , Encode=[" + encode + "]" ;
    103                        throw new RuntimeException( errMsg,ex );
    104                }
    105                catch ( IOException ex ) {
    106                        final String errMsg = "ファイル読込みエラーが発生しました。" + CR
    107                                                                +       " [" + file.getPath() + "] , Encode=[" + encode + "]" ;
    108                        throw new RuntimeException( errMsg,ex );
    109                }
    110                finally {
    111                        Closer.ioClose( reader );
    112                        helper.endFile( file );                                 // 6.2.0.0 (2015/02/27)
    113                }
    114        }
    115
    116        /**
    117         * データを読み込む場合の,区切り文字をセットします。
    118         *
    119         * なお，このメソッドは,サブクラスによっては,使用しない場合があります。
    120         * もし，使用しないサブクラスを作成する場合は, UnsupportedOperationException
    121         * を throw するように,サブクラスで実装して下さい。
    122         *
    123         * @param   sep 区切り文字
    124         */
    125        public void setSeparator( final String sep ) {
    126                if( sep != null ) { separator = sep; }
    127        }
    128
    129        /**
    130         * 読み取り元ファイルのエンコード文字列を指定します。
    131         * ファイルは、BufferedReader で受け取る為、本来は、エンコードは不要ですが、
    132         * 固定長ファイルの読み取り時のバイトコード分割時に、指定のエンコードで
    133         * 分割する必要があります。(例えば、半角文字は、Shift_JIS では、１バイト)
    134         *
    135         * @param   enc ファイルのエンコード文字列
    136         */
    137        public void setEncode( final String enc ) {
    138                encode = enc;
    139        }
    140}