org.cds06.speleograph.data.fileio.SpeleoFileWriter.java Source code

Java tutorial

Introduction

Here is the source code for org.cds06.speleograph.data.fileio.SpeleoFileWriter.java

Source

/*
 * Copyright (c) 2013 Philippe VIENNE
 *
 * This file is a part of SpeleoGraph
 *
 * SpeleoGraph is free software: you can redistribute
 * it and/or modify it under the terms of the GNU General
 * Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your
 * option) any later version.
 *
 * SpeleoGraph 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 General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with SpeleoGraph.
 * If not, see <http://www.gnu.org/licenses/>.
 */

package org.cds06.speleograph.data.fileio;

import org.apache.commons.io.output.FileWriterWithEncoding;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.cds06.speleograph.data.Item;
import org.cds06.speleograph.data.Series;
import org.jetbrains.annotations.NonNls;
import org.jfree.chart.axis.NumberAxis;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

/**
 * Writer for SpeleoGraph's Files.
 */
public class SpeleoFileWriter {

    @NonNls
    private static final Logger log = LoggerFactory.getLogger(SpeleoFileWriter.class);
    private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
    private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("##0.###");
    private FileWriterWithEncoding writer;
    private Integer allocatedColumns = 0;

    /**
     * Save all SpeleoGraph State in a .speleo File.
     *
     * @param destination The destination file, if it don't end with ".speleo", the name is edited.
     * @return true On success
     * @throws java.io.IOException On read/write errors.
     */
    public boolean save(File destination) throws IOException {
        if (!destination.getName().endsWith(".speleo")) {// NON-NLS
            destination = new File(destination.getAbsolutePath() + ".speleo");
        }
        writer = new FileWriterWithEncoding(destination, "UTF-8"); //NON-NLS
        List<Series> series = Series.getInstances();
        Integer[][] columns = new Integer[series.size()][];
        allocatedColumns = 0;
        write(SpeleoFileReader.SPELEOGRAPH_FILE_HEADER);
        write("headers");
        writeHeaders(series, columns);
        write("data");
        writeSeries(series, columns);
        write("eof");
        writer.close();
        return true;
    }

    private Integer writeHeaders(List<Series> series, Integer[][] columns) {
        ArrayList<NumberAxis> axes = new ArrayList<>();
        for (Series s : series) {
            NumberAxis axis = s.getAxis();
            if (axes.contains(axis))
                continue;
            axes.add(axis);
            int id = axes.indexOf(axis);
            boolean typeAxis = axis.equals(s.getType().getAxis());
            try {
                write("axis", Integer.toString(id), '"' + axis.getLabel() + '"',
                        DecimalFormat.getInstance().format(axis.getLowerBound()),
                        DecimalFormat.getInstance().format(axis.getUpperBound()), "type:" + (typeAxis ? "1" : "0"));
            } catch (Exception e) {
                log.error("Can not write axis to file", e);
            }
        }
        write("date", "", Integer.toString(allocatedColumns), "d/M/y H:m:s");
        allocatedColumns++;
        for (Series s : series) {
            String[] seriesDescriptor = { Integer.toString(allocatedColumns), s.getType().getName(),
                    s.getType().getUnit() };
            if (s.isMinMax()) {
                seriesDescriptor = ArrayUtils.add(seriesDescriptor, "min-max:1"); // NON-NLS
                seriesDescriptor = ArrayUtils.add(seriesDescriptor, "min:" + Integer.toString(allocatedColumns)); // NON-NLS
                seriesDescriptor = ArrayUtils.add(seriesDescriptor,
                        "max:" + Integer.toString(allocatedColumns + 1)); // NON-NLS
                columns[series.indexOf(s)] = new Integer[] { allocatedColumns, allocatedColumns + 1 };
                allocatedColumns++;
                allocatedColumns++;
            } else {
                columns[series.indexOf(s)] = new Integer[] { allocatedColumns };
                allocatedColumns++;
            }
            if (s.isShow())
                seriesDescriptor = ArrayUtils.add(seriesDescriptor, "show:1"); // NON-NLS
            if (s.getColor() != null)
                seriesDescriptor = ArrayUtils.add(seriesDescriptor, "color:" + s.getColor().getRGB()); // NON-NLS
            if (s.isMinMax())
                seriesDescriptor = ArrayUtils.add(seriesDescriptor, "stepped:1"); // NON-NLS
            if (s.getStyle() != null) {
                seriesDescriptor = ArrayUtils.add(seriesDescriptor, "style:" + s.getStyle().toString()); // NON-NLS
            }
            if (s.isNameHumanSet()) {
                seriesDescriptor = ArrayUtils.add(seriesDescriptor, "name:" + s.getName()); // NON-NLS
            }
            seriesDescriptor = ArrayUtils.add(seriesDescriptor, "axis:" + axes.indexOf(s.getAxis()));
            write(seriesDescriptor);
        }
        return allocatedColumns;
    }

    private void writeSeries(List<Series> series, Integer[][] columns) {
        for (Series s : series) {
            int seriesId = series.indexOf(s);
            switch (columns[seriesId].length) {
            case 1:
                writeColumn(columns[seriesId][0], s);
                break;
            case 2:
                writeMinMaxColumn(columns[seriesId], s);
                break;
            default:

            }
        }
    }

    private void writeColumn(Integer integer, Series s) {
        int column = integer;
        for (Item i : s.getItems()) {
            String[] line = new String[allocatedColumns];
            line[0] = DATE_FORMAT.format(i.getDate());
            line[column] = DECIMAL_FORMAT.format(i.getValue());
            write(resetNotNullArray(line));
        }
    }

    private void writeMinMaxColumn(Integer[] column, Series s) {
        int minColumn = column[0], maxColumn = column[1];
        for (Item i : s.getItems()) {
            String[] line = new String[allocatedColumns];
            line[0] = DATE_FORMAT.format(i.getDate());
            line[minColumn] = DECIMAL_FORMAT.format(i.getLow());
            line[maxColumn] = DECIMAL_FORMAT.format(i.getHigh());
            write(resetNotNullArray(line));
        }
    }

    /**
     * Make sure that there is not null element in a String array.
     *
     * @param line The array which can contains null elements
     * @return A String array without null elements.
     */
    private static String[] resetNotNullArray(String[] line) {
        for (int i1 = 0; i1 < line.length; i1++) {
            if (line[i1] == null)
                line[i1] = "";
        }
        return line;
    }

    private void write(@NonNls String... line) {
        final String lineToWrite = StringUtils.join(line, ';');
        try {
            writer.write(lineToWrite);
            writer.write("\n");
        } catch (IOException e) {
            log.error("Can not write line '" + lineToWrite + "'", e);
        }
    }

}