view artifacts/src/main/java/org/dive4elements/river/exports/fixings/DeltaWtExporter.java @ 9306:8024e51e828a

pdf export, issue 2.3.4.1.2
author gernotbelger
date Wed, 25 Jul 2018 18:36:26 +0200
parents 42c15e2f95fb
children a49fe0ebb297
line wrap: on
line source
/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
 * Software engineering by Intevation GmbH
 *
 * This file is Free Software under the GNU AGPL (>=v3)
 * and comes with ABSOLUTELY NO WARRANTY! Check out the
 * documentation coming with Dive4Elements River for details.
 */

package org.dive4elements.river.exports.fixings;

import java.io.IOException;
import java.io.OutputStream;
import java.text.DateFormat;
import java.text.MessageFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.TreeMap;

import org.apache.log4j.Logger;
import org.dive4elements.artifacts.CallMeta;
import org.dive4elements.river.artifacts.D4EArtifact;
import org.dive4elements.river.artifacts.access.RangeAccess;
import org.dive4elements.river.artifacts.access.RiverAccess;
import org.dive4elements.river.artifacts.common.DefaultCalculationResults;
import org.dive4elements.river.artifacts.common.ExportContextPDF;
import org.dive4elements.river.artifacts.common.GeneralResultType;
import org.dive4elements.river.artifacts.common.JasperReporter;
import org.dive4elements.river.artifacts.common.MetaAndTableJRDataSource;
import org.dive4elements.river.artifacts.model.CalculationResult;
import org.dive4elements.river.artifacts.model.fixings.AnalysisPeriod;
import org.dive4elements.river.artifacts.model.fixings.FixAnalysisResult;
import org.dive4elements.river.artifacts.model.fixings.QWD;
import org.dive4elements.river.artifacts.resources.Resources;
import org.dive4elements.river.artifacts.sinfo.util.CalculationUtils;
import org.dive4elements.river.artifacts.sinfo.util.RiverInfo;
import org.dive4elements.river.exports.AbstractExporter;
import org.dive4elements.river.utils.Formatter;
import org.dive4elements.river.utils.KMIndex;

import au.com.bytecode.opencsv.CSVWriter;
import net.sf.jasperreports.engine.JRException;

/** Exports fixation analysis deltaw(t) computation results to csv. */
public class DeltaWtExporter extends AbstractExporter {
    /** Private log. */
    private static Logger log = Logger.getLogger(DeltaWtExporter.class);

    private static final String JASPER_FILE = "/jasper/templates/fixanalysis.delta_wt.jrxml";

    public static final String CSV_KM_HEADER = "export.fixings.deltawt.csv.header.km";

    public static final String CSV_DELTA_W_HEADER = "export.fixings.deltawt.csv.header.deltaw";

    public static final String CSV_Q_HEADER = "export.fixings.deltawt.csv.header.q";

    public static final String CSV_W_HEADER = "export.fixings.deltawt.csv.header.w";

    public static final String CSV_TRANGE_HEADER = "export.fixings.deltawt.csv.header.time.range";

    public static final String CSV_T_HEADER = "export.fixings.deltawt.csv.header.t";

    public static final String CSV_T_FORMAT = "export.fixings.deltawt.csv.t.format";

    public static final String DEFAULT_CSV_KM_HEADER = "km";

    public static final String DEFAULT_CSV_DELTA_W_HEADER = "\u0394 W [cm]";

    public static final String DEFAULT_CSV_W_HEADER = "Wasserstand [m]";

    public static final String DEFAULT_CSV_Q_HEADER = "Abfluss [m\u00b3/s]";

    public static final String DEFAULT_CSV_T_HEADER = "Datum";

    public static final String DEFAULT_CSV_TRANGE_DESC_HEADER = "Status";

    public static final String CSV_REFERENCE = "export.fixings.deltawt.csv.reference";

    public static final String CSV_ANALYSIS = "export.fixings.deltawt.csv.analysis";

    public static final String DEFAULT_CSV_REFERENCE = "B";

    public static final String DEFAULT_CSV_ANALYSIS = "A{0,number,integer}";

    public static final String DEFAULT_CSV_T_FORMAT = "dd.MM.yyyy";

    protected List<KMIndex<AnalysisPeriod[]>> analysisPeriods;

    protected List<KMIndex<QWD[]>> referenceEvents;

    public DeltaWtExporter() {
        this.analysisPeriods = new ArrayList<>();
        this.referenceEvents = new ArrayList<>();
    }

    @Override
    protected void addData(final Object d) {
        log.debug("DeltaWtExporter.addData");
        if (!(d instanceof CalculationResult)) {
            log.warn("Invalid data type");
            return;
        }

        final Object data = ((CalculationResult) d).getData();
        if (!(data instanceof FixAnalysisResult)) {
            log.warn("Invalid data stored in result.");
        }
        final FixAnalysisResult result = (FixAnalysisResult) data;
        this.analysisPeriods.add(result.getAnalysisPeriods());
        this.referenceEvents.add(result.getReferenced());
    }

    @Override
    protected void writeCSVData(final CSVWriter writer) throws IOException {

        final boolean debug = log.isDebugEnabled();

        writeCSVHeader(writer);

        final TreeMap<Double, ArrayList<String[]>> sorted = getRows();
        for (final ArrayList<String[]> list : sorted.values()) {
            for (final String[] row : list) {
                writer.writeNext(row);
            }
        }

        writer.flush();
    }

    private TreeMap<Double, ArrayList<String[]>> getRows() {
        final NumberFormat kmF = getKMFormatter();
        final NumberFormat dwF = getDeltaWFormatter();
        final NumberFormat qF = getQFormatter();
        final NumberFormat wF = getWFormatter();

        final DateFormat dF = getDateFormatter();

        final TreeMap<Double, ArrayList<String[]>> sorted = new TreeMap<>();

        final String referenceS = getReference();

        for (final KMIndex<QWD[]> reference : this.referenceEvents) {

            for (final KMIndex.Entry<QWD[]> kmEntry : reference) {

                final Double km = kmEntry.getKm();

                ArrayList<String[]> list = sorted.get(km);

                if (list == null) {
                    list = new ArrayList<>();
                    sorted.put(km, list);
                }

                final String kmS = kmF.format(kmEntry.getKm());
                for (final QWD qwd : kmEntry.getValue()) {
                    final String deltaWS = dwF.format(qwd.getDeltaW());
                    final String qS = qF.format(qwd.getQ());
                    final String wS = wF.format(qwd.getW());
                    final String dateS = dF.format(qwd.getDate());

                    list.add(new String[] { kmS, dateS, qS, wS, referenceS, deltaWS });
                }
            }
        }

        // if (debug) {
        // log.debug("AnalysisPeriods: " + this.analysisPeriods.size());
        // }

        final String analysisTemplate = getAnalysisTemplate();

        for (final KMIndex<AnalysisPeriod[]> periods : this.analysisPeriods) {

            for (final KMIndex.Entry<AnalysisPeriod[]> kmEntry : periods) {

                final Double km = kmEntry.getKm();

                ArrayList<String[]> list = sorted.get(km);

                if (list == null) {
                    list = new ArrayList<>();
                    sorted.put(km, list);
                }

                final String kmS = kmF.format(kmEntry.getKm());
                int analysisCount = 1;

                for (final AnalysisPeriod period : kmEntry.getValue()) {
                    // Typically resulting in A1,A2...
                    final String analyisS = MessageFormat.format(analysisTemplate, analysisCount);
                    final QWD[] qwds = period.getQWDs();

                    if (qwds != null) {
                        for (final QWD qwd : qwds) {
                            final String deltaWS = dwF.format(qwd.getDeltaW());
                            final String qS = qF.format(qwd.getQ());
                            final String wS = wF.format(qwd.getW());
                            final String dateS = dF.format(qwd.getDate());

                            list.add(new String[] { kmS, dateS, qS, wS, analyisS, deltaWS });
                        }
                    }
                    ++analysisCount;
                }
            }
        }
        return sorted;

    }

    /** Template to create "State" strings like A1,A2... */
    protected String getAnalysisTemplate() {
        return Resources.getMsg(this.context.getMeta(), CSV_ANALYSIS, DEFAULT_CSV_ANALYSIS);
    }

    protected String getReference() {
        return Resources.getMsg(this.context.getMeta(), CSV_REFERENCE, DEFAULT_CSV_REFERENCE);
    }

    protected NumberFormat getKMFormatter() {
        return Formatter.getFixDeltaWKM(this.context);
    }

    protected NumberFormat getDeltaWFormatter() {
        return Formatter.getFixDeltaWDeltaW(this.context);
    }

    @Override
    protected NumberFormat getQFormatter() {
        return Formatter.getFixDeltaWQ(this.context);
    }

    @Override
    protected NumberFormat getWFormatter() {
        return Formatter.getFixDeltaWW(this.context);
    }

    protected DateFormat getDateFormatter() {
        final CallMeta meta = this.context.getMeta();
        return Formatter.getDateFormatter(meta, Resources.getMsg(meta, CSV_T_FORMAT, DEFAULT_CSV_T_FORMAT));
    }

    protected void writeCSVHeader(final CSVWriter writer) {
        log.debug("DeltaWtExporter.writeCSVHeader");

        /*
         * issue825
         * km; Ereignis, Abfluss, GEMESSENER Wasserstand;
         * Status (RECHTSBÜNDIG), del W
         */
        final RiverAccess river = new RiverAccess((D4EArtifact) this.master);
        final String unit = river.getRiver().getWstUnit().getName();

        writer.writeNext(new String[] { msg(CSV_KM_HEADER, DEFAULT_CSV_KM_HEADER), msg(CSV_T_HEADER, DEFAULT_CSV_T_HEADER),
                msg(CSV_Q_HEADER, DEFAULT_CSV_Q_HEADER), msg(CSV_W_HEADER, DEFAULT_CSV_W_HEADER, new Object[] { unit }),
                msg(CSV_TRANGE_HEADER, DEFAULT_CSV_TRANGE_DESC_HEADER), msg(CSV_DELTA_W_HEADER, DEFAULT_CSV_DELTA_W_HEADER) });
    }

    private void addMetaData(final MetaAndTableJRDataSource source) {
        final D4EArtifact flys = (D4EArtifact) this.master;
        final String user = CalculationUtils.findArtifactUser(this.context, flys);
        final RangeAccess ra = new RangeAccess(flys);
        final RiverInfo ri = new RiverInfo(ra.getRiver());

        final DefaultCalculationResults results = new DefaultCalculationResults(msg("calculation.analysis"), user, ri, ra.getRange());
        final ExportContextPDF contextPdf = new ExportContextPDF(this.context, results);
        contextPdf.addJRMetaDataDefaults(source);
        contextPdf.addJRMetaDataUSINFO(source);

        /* column headings */
        contextPdf.addJRMetadata(source, "station_header", GeneralResultType.station);
        contextPdf.addJRMetadata(source, "fix_date", msg(CSV_T_HEADER));
        contextPdf.addJRMetadata(source, "fix_q", msg(CSV_Q_HEADER));
        contextPdf.addJRMetadata(source, "fix_w", msg(CSV_W_HEADER, DEFAULT_CSV_W_HEADER, new Object[] { ri.getWstUnit() }));
        contextPdf.addJRMetadata(source, "fix_state", msg(CSV_TRANGE_HEADER));
        contextPdf.addJRMetadata(source, "fix_delta_w", msg(CSV_DELTA_W_HEADER));
    }

    @Override
    protected void writePDF(final OutputStream out) {
        final MetaAndTableJRDataSource source = new MetaAndTableJRDataSource();
        final String jasperFile = Resources.getMsg(this.context.getMeta(), JASPER_FILE);
        addMetaData(source);
        try {
            final TreeMap<Double, ArrayList<String[]>> sorted = getRows(); // Custom Result could be nice, too...
            for (final ArrayList<String[]> list : sorted.values()) {
                for (final String[] row : list) {
                    source.addData(row);
                }
            }
            final JasperReporter reporter = new JasperReporter();
            reporter.addReport(jasperFile, source);
            reporter.exportPDF(out);
        }
        catch (final JRException je) {
            log.warn("Error generating PDF Report!", je);
        }
    }
}

http://dive4elements.wald.intevation.org