jp.terasoluna.fw.file.dao.standard.AbstractFileLineIterator.java Source code

Java tutorial

Introduction

Here is the source code for jp.terasoluna.fw.file.dao.standard.AbstractFileLineIterator.java

Source

/*
 * Copyright (c) 2007 NTT DATA Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package jp.terasoluna.fw.file.dao.standard;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;

import jp.terasoluna.fw.file.annotation.FileFormat;
import jp.terasoluna.fw.file.annotation.InputFileColumn;
import jp.terasoluna.fw.file.annotation.PaddingType;
import jp.terasoluna.fw.file.annotation.StringConverter;
import jp.terasoluna.fw.file.annotation.TrimType;
import jp.terasoluna.fw.file.dao.FileException;
import jp.terasoluna.fw.file.dao.FileLineException;
import jp.terasoluna.fw.file.dao.FileLineIterator;

import org.apache.commons.lang3.StringUtils;

/**
 * (?)?
 * <p>
 * (?)?3??(CSV???) ??????? ??????<br>
 * ?{@link jp.terasoluna.fw.file.dao.FileLineIterator}????
 * </p>
 * ?????????????????????<br>
 * <ul>
 * <li>?(getHeader())</li>
 * <li>?(skip())</li>
 * <li>??(hasNext()?readLine())</li>
 * <li>?(getTrailer())</li>
 * </ul>
 * ?????????????? ???????????????<br>
 * ??????<code>IllegalStateException<code>????<br>
 * @see jp.terasoluna.fw.file.dao.FileLineIterator
 * @see jp.terasoluna.fw.file.dao.standard.CSVFileLineIterator
 * @see jp.terasoluna.fw.file.dao.standard.FixedFileLineIterator
 * @see jp.terasoluna.fw.file.dao.standard.VariableFileLineIterator
 * @see jp.terasoluna.fw.file.dao.standard.PlainFileLineIterator
 * @param <T> 
 */
public abstract class AbstractFileLineIterator<T> implements FileLineIterator<T> {

    /**
     * ??????
     */
    private static final int INITIAL_LINE_NO = -1;

    /**
     * ??
     */
    private String fileName = null;

    /**
     * ?
     */
    private Class<T> clazz = null;

    /**
     * 
     */
    private String lineFeedChar = System.getProperty("line.separator");

    /**
     * 
     */
    private String fileEncoding = System.getProperty("file.encoding");

    /**
     * 
     */
    private int headerLineCount = 0;

    /**
     * 
     */
    private int trailerLineCount = 0;

    /**
     * ????
     */
    private int currentLineCount = 0;

    /**
     * ?
     */
    private BufferedReader reader = null;

    /**
     * ?FieldAnnotation??
     */
    private Field[] fields = null;

    /**
     * ???
     */
    private InputFileColumn[] inputFileColumns = null;

    /**
     * ????Index??
     */
    private int[] columnIndexs = null;

    /**
     * ???????
     */
    private String[] columnFormats = null;

    /**
     * ???????
     */
    private int[] columnBytes = null;

    /**
     * 1????
     */
    private int totalBytes = 0;

    /**
     * ??????
     */
    private PaddingType[] paddingTypes = null;

    /**
     * ??????
     */
    private char[] paddingChars = null;

    /**
     * ??????
     */
    private TrimType[] trimTypes;

    /**
     * ????
     */
    private char[] trimChars;

    /**
     * ???????
     */
    private char[] columnEncloseChar;

    /**
     * ????
     */
    private StringConverter[] stringConverters = null;

    /**
     * ????
     */
    @SuppressWarnings("rawtypes")
    private static Map<Class, StringConverter> stringConverterCacheMap = new HashMap<Class, StringConverter>();

    /**
     * ?Field??setter??
     */
    private Method[] methods = null;

    /**
     * ??
     */
    private Map<String, ColumnParser> columnParserMap = null;

    /**
     * ?
     */
    private List<String> header = new ArrayList<String>();

    /**
     * ?
     */
    private List<String> trailer = new ArrayList<String>();

    /**
     * ??
     */
    private boolean readTrailer = false;

    /**
     * ???
     */
    private Queue<String> trailerQueue = null;

    /**
     * 1??
     */
    private LineReader lineReader = null;

    /**
     * ???
     */
    private boolean calledInit = false;

    /**
     * ??
     */
    private boolean enclosed = false;

    /**
     * <br>
     * ??????FileFormat ???<br>
     * ????????<br>
     * @param fileName ???
     * @param clazz 
     * @param columnParserMap ?
     * @throws FileException ??????
     */
    public AbstractFileLineIterator(String fileName, Class<T> clazz, Map<String, ColumnParser> columnParserMap) {
        // ?????
        if (fileName == null || "".equals(fileName)) {
            throw new FileException("fileName is required.", new IllegalArgumentException(), fileName);
        }

        // ???
        if (clazz == null) {
            throw new FileException("clazz is required.", new IllegalArgumentException(), fileName);
        }

        // ????
        if (columnParserMap == null || columnParserMap.isEmpty()) {
            throw new FileException("columnFormaterMap is required.", new IllegalArgumentException(), fileName);
        }

        // ???????
        try {
            clazz.newInstance();
        } catch (InstantiationException e) {
            throw new FileException("Failed in instantiation of clazz.", e, fileName);
        } catch (IllegalAccessException e) {
            throw new FileException("clazz's nullary  constructor is not accessible", e, fileName);
        }

        this.fileName = fileName;
        this.clazz = clazz;
        this.columnParserMap = columnParserMap;

        // FileFormat???
        FileFormat fileFormat = clazz.getAnnotation(FileFormat.class);

        // ?Class?FileFormat?????
        if (fileFormat == null) {
            throw new FileException("FileFormat annotation is not found.", new IllegalStateException(), fileName);
        }

        // ????????
        if (fileFormat.delimiter() == fileFormat.encloseChar()) {
            throw new FileException("Delimiter is the same as EncloseChar and is no use.",
                    new IllegalStateException(), fileName);
        }

        // ????????
        if (fileFormat.lineFeedChar() != null && !"".equals(fileFormat.lineFeedChar())) {
            this.lineFeedChar = fileFormat.lineFeedChar();
        }

        // ????????
        if (fileFormat.fileEncoding() != null && !"".equals(fileFormat.fileEncoding())) {
            this.fileEncoding = fileFormat.fileEncoding();
        }

        // ?
        this.headerLineCount = fileFormat.headerLineCount();

        // ?
        this.trailerLineCount = fileFormat.trailerLineCount();
    }

    /**
     * ??????????<br>
     * ?????????? true ???
     * @return ?????????? <code>true</code>
     * @throws FileException ?IOException????
     */
    @Override
    public boolean hasNext() {
        try {
            reader.mark(1);
            if (reader.read() != -1) {
                return true;
            }
        } catch (IOException e) {
            throw new FileException("Processing of reader was failed.", e, fileName);
        } finally {
            try {
                reader.reset();
            } catch (IOException e) {
                throw new FileException("Processing of reader#reset was failed.", e, fileName);
            }
        }

        return false;
    }

    /**
     * ?????<br>
     * <p>
     * ???????????<br>
     * ????????<br>
     * </p>
     * ?????InputFileColumn?? ?????<br>
     * ????????? ??????<br>
     * ???InputFileColumn????????????<br>
     * ??????????????<br>
     * <ul>
     * <li>?</li>
     * <li>?</li>
     * <li>??</li>
     * <li>?()?</li>
     * </ul>
     * @return 
     * @throws FileException ??????
     * @throws FileLineException ??????
     */
    @Override
    public T next() {
        if (readTrailer) {
            throw new FileLineException("Data part should be called before trailer part.",
                    new IllegalStateException(), fileName, currentLineCount);
        }

        if (!hasNext()) {
            throw new FileLineException("The data which can be acquired doesn't exist.",
                    new NoSuchElementException(), fileName, currentLineCount + 1);
        }

        T fileLineObject = null;

        // ?hasNext()??????null????
        String currentString = readLine();
        currentLineCount++;

        // ?????
        try {
            fileLineObject = clazz.newInstance();
        } catch (InstantiationException e) {
            throw new FileException("Failed in an instantiate of a FileLineObject.", e, fileName);
        } catch (IllegalAccessException e) {
            throw new FileException("Failed in an instantiate of a FileLineObject.", e, fileName);
        }

        // CSV????????
        // ????
        String[] columns = separateColumns(currentString);

        // ????????
        if (fields.length != columns.length) {
            throw new FileLineException("Column Count is different from " + "FileLineObject's column counts",
                    new IllegalStateException(), fileName, currentLineCount);
        }

        int columnIndex = -1;
        String columnString = null;

        for (int i = 0; i < fields.length; i++) {

            // JavaBean???
            columnIndex = columnIndexs[i];

            // 1??
            columnString = columns[columnIndex];

            // ???
            if (isCheckByte(columnBytes[i])) {
                try {
                    if (columnString.getBytes(fileEncoding).length != columnBytes[i]) {
                        throw new FileLineException("Data size is different from a set point " + "of a column.",
                                new IllegalStateException(), fileName, currentLineCount, fields[i].getName(),
                                columnIndex);
                    }
                } catch (UnsupportedEncodingException e) {
                    throw new FileException("fileEncoding which isn't supported was set.", e, fileName);
                }
            }

            // ?
            columnString = FileDAOUtility.trim(columnString, fileEncoding, trimChars[i], trimTypes[i]);

            // ?
            columnString = FileDAOUtility.padding(columnString, fileEncoding, columnBytes[i], paddingChars[i],
                    paddingTypes[i]);

            // ???
            columnString = stringConverters[i].convert(columnString);

            // ???
            // JavaBean???????????
            ColumnParser columnParser = columnParserMap.get(fields[i].getType().getName());
            try {
                columnParser.parse(columnString, fileLineObject, methods[i], columnFormats[i]);
            } catch (IllegalArgumentException e) {
                throw new FileLineException("Failed in coluomn data parsing.", e, fileName, currentLineCount,
                        fields[i].getName(), columnIndex);
            } catch (IllegalAccessException e) {
                throw new FileLineException("Failed in coluomn data parsing.", e, fileName, currentLineCount,
                        fields[i].getName(), columnIndex);
            } catch (InvocationTargetException e) {
                throw new FileLineException("Failed in coluomn data parsing.", e, fileName, currentLineCount,
                        fields[i].getName(), columnIndex);
            } catch (ParseException e) {
                throw new FileLineException("Failed in coluomn data parsing.", e, fileName, currentLineCount,
                        fields[i].getName(), columnIndex);
            }

        }

        return fileLineObject;
    }

    /**
     * ????<br>
     * Iterator????<br>
     * FileQueryDAO??????????????? UnsupportedOperationException?
     * @throws UnsupportedOperationException ???????
     */
    @Override
    public void remove() {
        throw new UnsupportedOperationException("remove() isn't supported.");
    }

    /**
     * ???<br>
     * ????????
     * <ul>
     * <li>?(Field)??</li>
     * <li>?(stringConverters)??</li>
     * <li>???(methods)??</li>
     * <li>????LineReader??</li>
     * <li>??</li>
     * <li>??</li>
     * </ul>
     * init()?AbstracFileLineIterator??? ???<br>
     * ??????2??????????
     * @throws FileException ??????
     * @throws FileLineException ????????
     */
    protected void init() {
        if (!calledInit) {
            // ????
            buildFields();

            if (isCheckEncloseChar()) {
                // ???????????
                if (isEnclosed()) {
                    throw new FileException("columnEncloseChar can not change.", new IllegalStateException(),
                            fileName);
                }
            }

            if (isCheckColumnAnnotationCount()) {
                // ??????????
                if (fields.length == 0) {
                    throw new FileException("InputFileColumn is not found.", new IllegalStateException(), fileName);
                }
            }

            buildStringConverters();
            buildMethods();

            try {
                // ????LineReader??
                buildLineReader();

                // ?????????
                buildHeader();
                buildTrailerQueue();
            } catch (FileException e) {
                if (this.reader != null) {
                    try {
                        closeFile();
                    } catch (FileException fe) {
                        // ???????????
                        // ??FileException?????
                    }
                }
                throw e;
            }

            calledInit = true;
        }
    }

    /**
     * ????LineReader??<br>
     * ?Reader?????????LineReader???<br>
     * ?0,1,2????????
     * @throws FileException LineReader??????
     */
    private void buildLineReader() {
        // ??Reader??
        try {
            this.reader = new BufferedReader(new InputStreamReader((new FileInputStream(fileName)), fileEncoding));
            if (!reader.markSupported()) {
                throw new FileException("BufferedReader of this JVM dose not support mark method");
            }
        } catch (UnsupportedEncodingException e) {
            throw new FileException("Failed in generation of reader.", e, fileName);
        } catch (FileNotFoundException e) {
            throw new FileException("Failed in generation of reader.", e, fileName);
        }

        // ???????LineReader??
        if (lineFeedChar.length() == 2) {
            // ?2
            if (!enclosed) {
                // ??
                lineReader = new LineFeed2LineReader(reader, lineFeedChar);
            } else {
                // ??
                lineReader = new EncloseCharLineFeed2LineReader(getDelimiter(), getEncloseChar(), columnEncloseChar,
                        reader, lineFeedChar);
            }
        } else if (lineFeedChar.length() == 1) {
            // ?1
            if (!enclosed) {
                // ??
                lineReader = new LineFeed1LineReader(reader, lineFeedChar);
            } else {
                // ??
                lineReader = new EncloseCharLineFeed1LineReader(getDelimiter(), getEncloseChar(), columnEncloseChar,
                        reader, lineFeedChar);
            }
        } else if (lineFeedChar.length() == 0) {
            // ?0
            lineReader = new LineFeed0LineReader(reader, fileEncoding, totalBytes);
        } else {
            throw new FileException("lineFeedChar length must be 0 or 1 or 2. but: " + lineFeedChar.length(),
                    new IllegalStateException(), fileName);
        }
    }

    /**
     * InputFileColumn????? ????<br>
     * ???????<br>
     * ????{@link InputFileColumn#columnIndex()}????? ?????<br>
     * ???{@link InputFileColumn#columnIndex()}???????? ???<br>
     * ???????? InputFileColumn?????????<br>
     * @throws FileException ?????
     */
    private void buildFields() {
        // ?
        List<Field[]> allFields = new ArrayList<Field[]>();

        // ?
        Class<?> tempClass = clazz;
        Field[] declaredFieldArray = null;
        int allFieldCount = 0;
        while (tempClass != null) {
            declaredFieldArray = tempClass.getDeclaredFields();
            allFields.add(declaredFieldArray);
            allFieldCount += declaredFieldArray.length;
            tempClass = tempClass.getSuperclass();
        }

        // ?????
        Field[] dataColumnFields = new Field[allFieldCount];

        InputFileColumn inputFileColumn = null;
        int maxColumnIndex = -1;
        int columnIndex = -1;
        int columnCount = 0;

        for (Field[] fields : allFields) {
            for (Field field : fields) {
                inputFileColumn = field.getAnnotation(InputFileColumn.class);
                if (inputFileColumn != null) {
                    // ????????
                    if (columnParserMap.get(field.getType().getName()) == null) {
                        throw new FileException(
                                "There is a type which isn't supported in a "
                                        + "mapping target field in FileLineObject.",
                                new IllegalStateException(), fileName);
                    }

                    columnIndex = inputFileColumn.columnIndex();
                    // Index??????
                    if (columnIndex < 0) {
                        throw new FileException("Column Index in FileLineObject is the minus " + "number.",
                                new IllegalStateException(), fileName);
                    }
                    // Index?????????
                    if (dataColumnFields.length <= columnIndex) {
                        throw new FileException(
                                "Column Index in FileLineObject is bigger than " + "the total number of the field.",
                                new IllegalStateException(), fileName);
                    }
                    // Index??????????
                    if (dataColumnFields[columnIndex] == null) {
                        dataColumnFields[columnIndex] = field;
                        if (maxColumnIndex < columnIndex) {
                            maxColumnIndex = columnIndex;
                        }
                        columnCount++;
                    } else {
                        throw new FileException("Column Index is duplicate : " + columnIndex, fileName);
                    }
                }
            }
        }

        // columnIndex????????
        if (columnCount != (maxColumnIndex + 1)) {
            throw new FileException("columnIndex in FileLineObject is not sequential order.",
                    new IllegalStateException(), fileName);
        }

        // (null?)
        if (dataColumnFields.length == columnCount) {
            this.fields = dataColumnFields;
        } else {
            this.fields = new Field[columnCount];
            System.arraycopy(dataColumnFields, 0, this.fields, 0, columnCount);
        }

        // InputFileColumn???StringConverter
        inputFileColumns = new InputFileColumn[fields.length];
        columnIndexs = new int[fields.length];
        columnFormats = new String[fields.length];
        columnBytes = new int[fields.length];
        paddingTypes = new PaddingType[fields.length];
        paddingChars = new char[fields.length];
        trimTypes = new TrimType[fields.length];
        trimChars = new char[fields.length];

        // ???FileFormat???
        columnEncloseChar = new char[fields.length];
        if (getEncloseChar() != Character.MIN_VALUE) {
            enclosed = true;
            for (int index = 0; index < fields.length; index++) {
                columnEncloseChar[index] = getEncloseChar();
            }
        }

        for (int i = 0; i < fields.length; i++) {
            inputFileColumns[i] = fields[i].getAnnotation(InputFileColumn.class);
            columnIndexs[i] = inputFileColumns[i].columnIndex();
            columnFormats[i] = inputFileColumns[i].columnFormat();
            columnBytes[i] = inputFileColumns[i].bytes();
            totalBytes += columnBytes[i];
            paddingTypes[i] = inputFileColumns[i].paddingType();
            paddingChars[i] = inputFileColumns[i].paddingChar();
            trimTypes[i] = inputFileColumns[i].trimType();
            trimChars[i] = inputFileColumns[i].trimChar();

            // ?inputFileColumns?????
            if (inputFileColumns[i].columnEncloseChar() != Character.MIN_VALUE) {
                columnEncloseChar[i] = inputFileColumns[i].columnEncloseChar();
                enclosed = true;
            }
        }
    }

    /**
     * ???????<br>
     * ??????? ??????<br>
     * ??????????? ??<br>
     * @throws FileLineException ???????
     */
    private void buildStringConverters() {

        // ????
        StringConverter[] dataColumnStringConverters = new StringConverter[fields.length];

        InputFileColumn inputFileColumn = null;
        Class<? extends StringConverter> converterKind = null;

        for (int i = 0; i < fields.length; i++) {

            // JavaBean????
            inputFileColumn = inputFileColumns[i];

            // inputFileColumn.stringConverter()????
            try {
                // ????
                converterKind = inputFileColumn.stringConverter();

                // ???????????
                if (stringConverterCacheMap.containsKey(converterKind)) {
                    // ?????????
                    dataColumnStringConverters[i] = stringConverterCacheMap.get(converterKind);

                } else {
                    // ????????
                    dataColumnStringConverters[i] = converterKind.newInstance();
                    stringConverterCacheMap.put(converterKind, dataColumnStringConverters[i]);
                }

            } catch (InstantiationException e) {
                throw new FileLineException("Failed in an instantiate of a stringConverter.", e, fileName,
                        INITIAL_LINE_NO, fields[i].getName(), inputFileColumn.columnIndex());

            } catch (IllegalAccessException e) {
                throw new FileLineException("Failed in an instantiate of a stringConverter.", e, fileName,
                        INITIAL_LINE_NO, fields[i].getName(), inputFileColumn.columnIndex());
            }
        }
        this.stringConverters = dataColumnStringConverters;
    }

    /**
     * ??setter?????<br>
     * ??setter????<br>
     * <ul>
     * <li>??????????set?????</li>
     * </ul>
     * setter??????????
     * @throws FileException setter????????
     */
    private void buildMethods() {
        Method[] dataColumnSetMethods = new Method[fields.length];
        StringBuilder setterName = new StringBuilder();
        String fieldName = null;

        for (int i = 0; i < fields.length; i++) {
            // JavaBean??????????
            fieldName = fields[i].getName();

            // ????setter??????
            setterName.setLength(0);
            setterName.append("set");
            setterName.append(StringUtils.upperCase(fieldName.substring(0, 1)));
            setterName.append(fieldName.substring(1, fieldName.length()));

            // setter???
            // fields[i].getType()?????
            try {
                dataColumnSetMethods[i] = clazz.getMethod(setterName.toString(),
                        new Class[] { fields[i].getType() });
            } catch (NoSuchMethodException e) {
                throw new FileException("The setter method of column doesn't exist.", e, fileName);
            }
        }
        this.methods = dataColumnSetMethods;
    }

    /**
     * ???<br>
     * ??????????<br>
     * @throws FileException ??????
     */
    private void buildHeader() {
        if (0 < headerLineCount) {
            for (int i = 0; i < headerLineCount; i++) {
                if (!hasNext()) {
                    throw new FileException("The data which can be acquired doesn't exist.",
                            new NoSuchElementException(), fileName);
                }
                try {
                    header.add(lineReader.readLine());
                } catch (FileException e) {
                    throw new FileException("Error occurred by reading processing of a File.", e, fileName);
                }
            }
        }
    }

    /**
     * ???<br>
     * ?????????? ?????????<br>
     * ????????????????<br>
     * ??????????<br>
     * ??????????<br>
     * @throws FileException ???????
     */
    private void buildTrailerQueue() {
        if (0 < trailerLineCount) {
            // ??
            trailerQueue = new ArrayBlockingQueue<String>(trailerLineCount);

            // ???
            for (int i = 0; i < trailerLineCount; i++) {
                if (!hasNext()) {
                    throw new FileException("The data which can be acquired doesn't exist.",
                            new NoSuchElementException(), fileName);
                }
                try {
                    trailerQueue.add(lineReader.readLine());
                } catch (FileException e) {
                    throw new FileException("Error occurred by reading processing of a File.", e, fileName);
                }
            }
        }
    }

    /**
     * ??<br>
     * @throws FileException ?????
     */
    @Override
    public void closeFile() {
        try {
            reader.close();
        } catch (IOException e) {
            throw new FileException("Processing of reader was failed.", e, fileName);
        }
    }

    /**
     * ???<br>
     * ???????????????? ?
     * @return header ?
     */
    @Override
    public List<String> getHeader() {
        return header;
    }

    /**
     * ???<br>
     * ?????????????<br>
     * ????????????<br>
     * <b>?</b><br>
     * ???????????<br>
     * @return ?
     * @throws FileException ??????
     */
    @Override
    public List<String> getTrailer() {
        // ???????
        if (!readTrailer) {
            String currentData = null;
            // ???????
            while (hasNext()) {
                try {
                    currentData = lineReader.readLine();
                } catch (FileException e) {
                    throw new FileException("Processing of lineReader was failed.", e, fileName);
                }
                if (0 < trailerLineCount) {
                    trailerQueue.poll();
                    trailerQueue.add(currentData);
                }
            }

            // ????
            if (0 < trailerLineCount) {
                int trailerQueueLength = trailerQueue.size();

                for (int i = 0; i < trailerQueueLength; i++) {
                    trailer.add(trailerQueue.poll());
                }
            }
            readTrailer = true;
        }
        return trailer;
    }

    /**
     * ??1?????????<br>
     * ?????????? ?<br>
     * ???LineReader?1??????<br>
     * ??????LineReader????1??? ?<br>
     * ???1??????null?
     * @return ??
     * @throws FileException ??????
     */
    protected String readLine() {

        // ??????null?
        if (!hasNext()) {
            return null;
        }

        // ?1???
        String currentReadLineString = null;
        try {
            currentReadLineString = lineReader.readLine();
        } catch (FileException e) {
            throw new FileException("Processing of lineReader was failed.", e, fileName);
        }

        // ???????????
        // ???1???
        if (0 < trailerLineCount) {
            String pollingLineString = trailerQueue.poll();
            trailerQueue.add(currentReadLineString);
            return pollingLineString;
        }

        return currentReadLineString;
    }

    /**
     * ??????<br>
     * @param skipLines ???
     */
    @Override
    public void skip(int skipLines) {
        for (int i = 0; i < skipLines; i++) {
            if (!hasNext()) {
                throw new FileLineException("The data which can be acquired doesn't exist.",
                        new NoSuchElementException(), fileName, currentLineCount + 1);
            }
            readLine();
            currentLineCount++;
        }
    }

    /**
     * ??
     * @return 
     */
    protected abstract char getDelimiter();

    /**
     * ???
     * @return ?
     */
    protected abstract char getEncloseChar();

    /**
     * ???? ???<br>
     * <code>fileLineString</code>?<code>null</code>???? ?????????<code>String</code>????<br>
     * ???????
     * @param fileLineString ?
     * @return ????
     */
    protected abstract String[] separateColumns(String fileLineString);

    /**
     * ???????
     * @param inputFileColumn ?InputFileColumn
     * @return ?????(1?)??true
     */
    protected boolean isCheckByte(InputFileColumn inputFileColumn) {
        if (0 < inputFileColumn.bytes()) {
            return true;
        }
        return false;
    }

    /**
     * ???????
     * @param columnByte ??
     * @return ?????(1?)??true
     */
    protected boolean isCheckByte(int columnByte) {
        if (0 < columnByte) {
            return true;
        }
        return false;
    }

    /**
     * ??
     * @return 
     */
    protected String getLineFeedChar() {
        return lineFeedChar;
    }

    /**
     * ?
     * @param 
     */
    protected void setLineFeedChar(String lineFeedChar) {
        this.lineFeedChar = lineFeedChar;
    }

    /**
     * ??
     * @return 
     */
    protected String getFileEncoding() {
        return fileEncoding;
    }

    /**
     * ??
     * @return 
     */
    protected int getHeaderLineCount() {
        return headerLineCount;
    }

    /**
     * ??
     * @return 
     */
    protected int getTrailerLineCount() {
        return trailerLineCount;
    }

    /**
     * ???????
     * @return ????
     */
    public int getCurrentLineCount() {
        return currentLineCount;
    }

    /**
     * ?FieldAnnotation????
     * @return ?FieldAnnotation??
     */
    protected Field[] getFields() {
        return fields;
    }

    /**
     * ????
     * @return fileName ??
     */
    protected String getFileName() {
        return fileName;
    }

    /**
     * ????
     * @return columnEncloseChar ?
     */
    protected char[] getColumnEncloseChar() {
        return columnEncloseChar;
    }

    /**
     * ???????
     * @return enclosed ?
     */
    protected boolean isEnclosed() {
        return enclosed;
    }

    /**
     * ?????
     * @return columnBytes ???
     */
    protected int[] getColumnBytes() {
        return columnBytes;
    }

    /**
     * 1????
     * @return totalBytes 1??
     */
    protected int getTotalBytes() {
        return totalBytes;
    }

    /**
     * ??????????????
     * @return ????true
     */
    protected boolean isCheckEncloseChar() {
        return false;
    }

    /**
     * ????????????
     * @return ????true
     */
    protected boolean isCheckColumnAnnotationCount() {
        return true;
    }
}