/*
 This file is part of the software framework JStatCom, 
 a library for building applications for data based analysis.

 Copyright (C) 2000-2005  Markus Kraetzig

 This library is free software; you can redistribute it and/or modify
 it under the terms of the GNU Lesser General Public License as
 published by the Free Software Foundation; either version 2.1 of the
 License, or (at your option) any later version.

 This library is distributed in the hope that it will be useful, but
 WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 Lesser General Public License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with this library; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 USA
 */

package com.jstatcom.io;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import jxl.Sheet;
import jxl.Workbook;
import jxl.write.Label;
import jxl.write.Number;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;

import com.jstatcom.component.TopFrameReference;
import com.jstatcom.model.JSCConstants;
import com.jstatcom.model.JSCData;
import com.jstatcom.model.JSCDate;
import com.jstatcom.model.JSCNArray;
import com.jstatcom.model.JSCSArray;
import com.jstatcom.model.JSCTypeDef;
import com.jstatcom.model.JSCTypes;
import com.jstatcom.model.SymbolTable;
import com.jstatcom.ts.TS;
import com.jstatcom.ts.TSDate;
import com.jstatcom.ts.TSDateRange;

/**
 * Import handler for Excel data files. It is designed as a singleton.
 * 
 * @author Markus Kraetzig 
 */
public final class TSExcelHandler implements DataHandler {
    private boolean noDialog = false;

    private TSExcelDialog tableDialog = null;

    private final SymbolTable symbolTable = new SymbolTable("TSExcelImport",
            false);

    private static final TSExcelHandler handler = new TSExcelHandler();

    /**
     * Creates a TSExcelHandler.
     */
    private TSExcelHandler() {
        super();
    }

    /**
     * Gets the singleton instance of this handler.
     * 
     * @return instance
     */
    public static TSExcelHandler getInstance() {
        return handler;
    }

    /**
     * Initiates parsing of data file.
     * 
     * @param dataFile
     *            the file to read in
     * @return true of import was ok, false if
     *         canceled or erroneous
     * @throws IllegalArgumentException
     *             if (dataFile == null || !dataFile.isFile())
     */
    public boolean importData(File dataFile) {
        if (dataFile == null || !dataFile.isFile())
            throw new IllegalArgumentException("Invalid data file " + dataFile
                    + ".");
        Workbook w = null;
        symbolTable.clear();
        try {
            w = Workbook.getWorkbook(dataFile);
            parseToDataSet(w);
        } catch (Throwable t) {
            throw new RuntimeException(t.getMessage());
        }
        w.close();
        if (symbolTable.isEmpty())
            return false;
        return true;
    }

    /**
     * Gets the imported data according to an instance of
     * TSImportTypes.
     * 
     * @param type
     *            the elementtype of a time series dataset
     * @return the data stored as JSCData
     * @throws IllegalArgumentException
     *             if (type == null)
     * @throws IllegalStateException
     *             if nothing was imported before
     */
    public JSCData getData(ImportTypes type) {

        if (symbolTable == null)
            throw new IllegalStateException("There was nothing imported yet.");

        if (type == null)
            throw new IllegalArgumentException("Argument was null.");

        return symbolTable.getJSCData(new JSCTypeDef(type.name(), type.type()));
    }

    /**
     * Gets the dialog to ask for user information.
     */
    private TSExcelDialog getTableDialog() {
        if (tableDialog == null)
            tableDialog = new TSExcelDialog(TopFrameReference.getTopFrameRef(),
                    true);
        tableDialog.setLocationRelativeTo(TopFrameReference.getTopFrameRef());
        return tableDialog;
    }

    private void parseToDataSet(Workbook w) {
        // Get the sheet you want to read from Excel file.
        int sheet = 0;
        String[] sheetNames = new String[w.getNumberOfSheets()];
        Sheet[] sheets = w.getSheets();
        for (int i = 0; i < sheetNames.length; i++)
            sheetNames[i] = sheets[i].getName();

        if (w.getNumberOfSheets() > 0) {
            getTableDialog().setSheets(sheetNames);
            if (!noDialog)
                getTableDialog().setVisible(true);
            sheet = getTableDialog().getSelectedSheet();
            if (getTableDialog().isCanceled())
                return;
        } else
            throw new RuntimeException("File contains no sheets.");

        Sheet s = w.getSheet(sheet);
        List labelsList = new ArrayList();
        double[][] data = ExcelHelper.extractNumberArray(w, sheet, false, null,
                labelsList);

        String[] varNames = new String[s.getColumns()];
        // Find the variable names (the first LABEL entries in each column).
        for (int i = 0; i < s.getColumns(); i++) {
            varNames[i] = "var" + (i + 1) + "_sheet" + (sheet + 1);
            String name = labelsList.get(i);
            name = name.replace(' ', '_');
            if (JSCConstants.isValidName(name) == null)
                varNames[i] = name;
        }

        // Get the first date and the periodicity from tableDialog and
        // construct the datasets.

        symbolTable.set(new JSCNArray(TSImportTypes.DATA.name(), data));
        symbolTable.set(new JSCDate(TSImportTypes.STARTDATE.name(),
                getTableDialog().getTSDate()));
        symbolTable.set(new JSCSArray(TSImportTypes.VARNAMES.name(), varNames));

    }

    public void exportTS(File file, TS[] ts, String description) {
        if (file == null)
            throw new IllegalArgumentException("File argument was null.");

        if (ts == null)
            throw new IllegalArgumentException("Time series argument was null.");

        if (ts.length == 0)
            return;

        TSDateRange mergedRange = TSDateRange.getMergedRange(ts);
        Label[] labels = new Label[ts.length];
        for (int i = 0; i < ts.length; i++)
            labels[i] = new Label(i, 0, ts[i].name());

        try {
            WritableWorkbook workbook = Workbook.createWorkbook(file);
            WritableSheet s1 = workbook.createSheet("Time Series", 0);

            // names
            for (int i = 0; i < labels.length; i++) {
                s1.addCell(labels[i]);
                s1.setColumnView(i, 25);
            }

            // data
            for (int i = 0; i < mergedRange.numOfObs(); i++) {
                TSDate currentDate = mergedRange.dateForIndex(i);
                for (int j = 0; j < ts.length; j++) {
                    Number num = new Number(j, i + 1, ts[j]
                            .valueAt(currentDate));
                    s1.addCell(num);
                }
            }

            workbook.write();
            workbook.close();

        } catch (Throwable ex) {
            throw new RuntimeException(ex.getMessage());
        }

    }

    public void exportData(File file, JSCData data, String description) {
        if (file == null)
            throw new IllegalArgumentException("File argument was null.");

        if (data == null)
            throw new IllegalArgumentException("Data argument was null.");

        if (data.type() != JSCTypes.NARRAY)
            throw new IllegalArgumentException("Data of type \"" + data.type()
                    + "\" cannot be stored in Excel format.");

        if (data.isEmpty())
            return;

        JSCNArray nArray = (JSCNArray) data;
        Label[] labels = new Label[nArray.cols()];
        if (labels.length == 1)
            labels[0] = new Label(0, 0, nArray.name());
        else
            for (int i = 0; i < labels.length; i++)
                labels[i] = new Label(i, 0, nArray.name() + "_" + (i + 1));

        try {
            WritableWorkbook workbook = Workbook.createWorkbook(file);
            WritableSheet s1 = workbook.createSheet(nArray.name(), 0);

            // names
            for (int i = 0; i < labels.length; i++) {
                s1.addCell(labels[i]);
                s1.setColumnView(i, 25);
            }

            // data
            for (int i = 0; i < nArray.rows(); i++) {
                for (int j = 0; j < nArray.cols(); j++) {
                    Number num = new Number(j, i + 1, nArray.doubleAt(i, j));
                    s1.addCell(num);
                }
            }

            workbook.write();
            workbook.close();

        } catch (Throwable ex) {
            throw new RuntimeException(ex.getMessage());
        }

    }

    /**
     * Sets this handler in test mode. No user dialog is shown, default values
     * are used instead. This is helpful for running automated unit tests.
     * 
     * @param noDialog
     */
    public void setTestMode(boolean noDialog) {
        this.noDialog = noDialog;
    }
}
 

Ads help maintain this website.