package jp.sourceforge.glad.org.seasar.extension.dataset.impl;

import java.io.File;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.seasar.extension.dataset.DataRow;
import org.seasar.extension.dataset.DataTable;
import org.seasar.extension.dataset.impl.DataRowImpl;
import org.seasar.framework.util.ArrayMap;
import org.seasar.framework.util.ClassUtil;
import org.seasar.framework.util.FieldUtil;
import org.seasar.framework.util.MethodUtil;

public class XlsReader extends org.seasar.extension.dataset.impl.XlsReader {

    public XlsReader(String path) {
        super(path);
    }

    public XlsReader(String path, boolean trimString) {
        super(path, trimString);
    }

    public XlsReader(String dirName, String fileName) {
        super(dirName, fileName);
    }

    public XlsReader(String dirName, String fileName, boolean trimString) {
        super(dirName, fileName, trimString);
    }

    public XlsReader(File file) {
        super(file);
    }

    public XlsReader(File file, boolean trimString) {
        super(file, trimString);
    }

    public XlsReader(File dir, String fileName) {
        super(dir, fileName);
    }

    public XlsReader(File dir, String fileName, boolean trimString) {
        super(dir, fileName, trimString);
    }

    public XlsReader(InputStream in) {
        super(in);
    }

    public XlsReader(InputStream in, boolean trimString) {
        super(in, trimString);
    }

    @Override
    protected void setupRow(DataTable table, HSSFRow row) {
        DataRow dataRow = table.addRow();
        for (int i = 0; i < table.getColumnSize(); ++i) {
            HSSFCell cell = row.getCell((short) i);
            Object value = getValue(cell);
            DataRowUtil.setValue(dataRow, i, value);
        }
    }

    static class DataRowUtil {

        static final Field valuesField;
        static final Method modifyMethod;

        static {
            valuesField = ClassUtil.getDeclaredField(
                    DataRowImpl.class, "values_");
            valuesField.setAccessible(true);
            modifyMethod = ClassUtil.getDeclaredMethod(
                    DataRowImpl.class, "modify", new Class[0]);
            modifyMethod.setAccessible(true);
        }

        static void setValue(DataRow dataRow, int index, Object value) {
            if (!"*".equals(value)) {
                dataRow.setValue(index, value);
                return;
            }
            ArrayMap values = (ArrayMap) FieldUtil.get(valuesField, dataRow);
            values.set(index, "*");
            MethodUtil.invoke(modifyMethod, dataRow, new Object[0]);
        }

    }

}
