gernotbelger@8928: /** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde gernotbelger@8928: * Software engineering by gernotbelger@8928: * Björnsen Beratende Ingenieure GmbH gernotbelger@8928: * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt gernotbelger@8928: * gernotbelger@8928: * This file is Free Software under the GNU AGPL (>=v3) gernotbelger@8928: * and comes with ABSOLUTELY NO WARRANTY! Check out the gernotbelger@8928: * documentation coming with Dive4Elements River for details. gernotbelger@8928: */ gernotbelger@8928: package org.dive4elements.river.artifacts.sinfo.common; gernotbelger@8928: gernotbelger@8928: import java.io.OutputStream; gernotbelger@8946: import java.text.DateFormat; gernotbelger@8946: import java.text.NumberFormat; gernotbelger@8928: import java.util.Collection; gernotbelger@8946: import java.util.Date; gernotbelger@8928: import java.util.HashMap; gernotbelger@8946: import java.util.Locale; gernotbelger@8928: import java.util.Map; gernotbelger@8928: gernotbelger@8946: import org.apache.commons.lang.math.DoubleRange; gernotbelger@8928: import org.apache.log4j.Logger; gernotbelger@8928: import org.dive4elements.artifacts.CallMeta; gernotbelger@8928: import org.dive4elements.artifacts.common.utils.Config; gernotbelger@8946: import org.dive4elements.river.FLYS; gernotbelger@8928: import org.dive4elements.river.artifacts.model.CalculationResult; gernotbelger@8928: import org.dive4elements.river.artifacts.resources.Resources; gernotbelger@8946: import org.dive4elements.river.artifacts.sinfo.SInfoI18NStrings; gernotbelger@8946: import org.dive4elements.river.artifacts.sinfo.util.BedHeightInfo; gernotbelger@8928: import org.dive4elements.river.artifacts.sinfo.util.MetaAndTableJRDataSource; gernotbelger@8928: import org.dive4elements.river.artifacts.sinfo.util.RiverInfo; gernotbelger@8946: import org.dive4elements.river.artifacts.sinfo.util.WstInfo; gernotbelger@8928: import org.dive4elements.river.exports.AbstractExporter; gernotbelger@8928: gernotbelger@8928: import au.com.bytecode.opencsv.CSVWriter; gernotbelger@8928: import net.sf.jasperreports.engine.JRDataSource; gernotbelger@8928: import net.sf.jasperreports.engine.JRException; gernotbelger@8928: import net.sf.jasperreports.engine.JasperExportManager; gernotbelger@8928: import net.sf.jasperreports.engine.JasperFillManager; gernotbelger@8928: import net.sf.jasperreports.engine.JasperPrint; gernotbelger@8928: gernotbelger@8928: /** gernotbelger@8928: * @author Gernot Belger gernotbelger@8928: */ gernotbelger@8928: public abstract class AbstractSInfoExporter, RESULTS extends AbstractSInfoCalculationResults> extends AbstractExporter { gernotbelger@8928: gernotbelger@8946: private static final String CSV_META_HEADER_SOUNDING = "sinfo.export.flow_depth.csv.meta.header.sounding"; gernotbelger@8946: gernotbelger@8946: private static final String CSV_META_HEADER_SOUNDING_YEAR = "sinfo.export.flow_depth.csv.meta.header.sounding.year"; gernotbelger@8946: gernotbelger@8946: private static final String CSV_META_HEADER_SOUNDING_TYPE = "sinfo.export.flow_depth.csv.meta.header.sounding.type"; gernotbelger@8946: gernotbelger@8946: private static final String CSV_META_HEADER_SOUNDING_EVALUATOR = "sinfo.export.flow_depth.csv.meta.header.sounding.evaluator"; gernotbelger@8946: gernotbelger@8946: private static final String CSV_META_HEADER_SOUNDING_PRJ = "sinfo.export.flow_depth.csv.meta.header.sounding.prj"; gernotbelger@8946: gernotbelger@8946: private static final String CSV_META_HEADER_SOUNDING_ELEVATIOIN_MODEL = "sinfo.export.flow_depth.csv.meta.header.sounding.elevationmodel"; gernotbelger@8946: gernotbelger@8946: private static final String CSV_META_HEADER_SOUNDING_ELEVATIOIN_MODEL_ORIGINAL = "sinfo.export.flow_depth.csv.meta.header.sounding.elevationmodel.original"; gernotbelger@8946: gernotbelger@8928: /** The storage that contains the current calculation result. */ gernotbelger@8928: private RESULTS data = null; gernotbelger@8928: gernotbelger@8928: protected abstract Logger getLog(); gernotbelger@8928: gernotbelger@8928: public RESULTS getData() { gernotbelger@8928: return this.data; gernotbelger@8928: } gernotbelger@8928: gernotbelger@8928: @Override gernotbelger@8928: protected final void addData(final Object d) { gernotbelger@8928: /* reset */ gernotbelger@8928: this.data = null; gernotbelger@8928: gernotbelger@8928: if (d instanceof CalculationResult) { gernotbelger@8928: gernotbelger@8928: final Object dat = ((CalculationResult) d).getData(); gernotbelger@8938: if (dat != null) { gernotbelger@8938: @SuppressWarnings("unchecked") gernotbelger@8938: final RESULTS result = (RESULTS) dat; gernotbelger@8938: this.data = result; gernotbelger@8938: } gernotbelger@8928: } gernotbelger@8928: } gernotbelger@8928: gernotbelger@8928: @Override gernotbelger@8928: protected final void writeCSVData(final CSVWriter writer) { gernotbelger@8928: getLog().info("writeCSVData"); gernotbelger@8928: gernotbelger@8928: /* fetch calculation results */ gernotbelger@8928: final RESULTS results = this.data; gernotbelger@8928: gernotbelger@8928: final RiverInfo river = results.getRiver(); gernotbelger@8928: gernotbelger@8928: /* write as csv */ gernotbelger@8938: writeCSVGlobalMetadata(writer, results); gernotbelger@8938: writeCSVHeader(writer, results, river); gernotbelger@8928: gernotbelger@8928: for (final RESULT result : results.getResults()) { gernotbelger@8938: writeCSVResult(writer, results, result); gernotbelger@8928: } gernotbelger@8928: } gernotbelger@8928: gernotbelger@8938: protected abstract void writeCSVHeader(final CSVWriter writer, final RESULTS results, final RiverInfo river); gernotbelger@8928: gernotbelger@8938: /** gernotbelger@8938: * Add metadata that is once written to the top of the file. gernotbelger@8938: */ gernotbelger@8938: protected abstract void writeCSVGlobalMetadata(final CSVWriter writer, final RESULTS results); gernotbelger@8928: gernotbelger@8928: protected final void writeCSVMetaEntry(final CSVWriter writer, final String message, final Object... messageArgs) { gernotbelger@8928: gernotbelger@8928: final CallMeta meta = this.context.getMeta(); gernotbelger@8928: gernotbelger@8928: writer.writeNext(new String[] { Resources.getMsg(meta, message, message, messageArgs) }); gernotbelger@8928: } gernotbelger@8928: gernotbelger@8938: protected final void writeCSVResult(final CSVWriter writer, final RESULTS results, final RESULT result) { gernotbelger@8928: gernotbelger@8938: writeCSVResultMetadata(writer, results, result); gernotbelger@8928: gernotbelger@8928: /* nwo the value rows */ gernotbelger@8928: final Collection rows = result.getRows(); gernotbelger@8928: for (final ROW row : rows) { gernotbelger@8938: writeCSVRow(writer, results, row); gernotbelger@8928: } gernotbelger@8928: } gernotbelger@8928: gernotbelger@8938: /** gernotbelger@8938: * Add metadata that is written once per result set. gernotbelger@8938: */ gernotbelger@8938: protected abstract void writeCSVResultMetadata(CSVWriter writer, RESULTS results, RESULT result); gernotbelger@8928: gernotbelger@8938: protected final void writeCSVRow(final CSVWriter writer, final RESULTS results, final ROW row) { gernotbelger@8928: getLog().debug("writeCSVFlowDepthRow"); gernotbelger@8928: gernotbelger@8938: final String[] formattedRow = formatCSVRow(results, row); gernotbelger@8928: writer.writeNext(formattedRow); gernotbelger@8928: } gernotbelger@8928: gernotbelger@8938: protected abstract String[] formatCSVRow(RESULTS results, final ROW row); gernotbelger@8928: gernotbelger@8928: @Override gernotbelger@8928: protected final void writePDF(final OutputStream outStream) { gernotbelger@8928: getLog().debug("write PDF"); gernotbelger@8928: gernotbelger@8928: final JRDataSource source = createJRData(); gernotbelger@8928: gernotbelger@8928: final String confPath = Config.getConfigDirectory().toString(); gernotbelger@8928: gernotbelger@8928: // FIXME: distinguish between with and without tkh: we need two jasper reports! gernotbelger@8928: gernotbelger@8928: final Map parameters = new HashMap<>(); gernotbelger@8928: parameters.put("ReportTitle", "Exported Data"); gernotbelger@8928: gernotbelger@8928: try { gernotbelger@8928: final String jasperPath = confPath + getJasperFile(); gernotbelger@8928: gernotbelger@8928: final JasperPrint print = JasperFillManager.fillReport(jasperPath, parameters, source); gernotbelger@8928: JasperExportManager.exportReportToPdfStream(print, outStream); gernotbelger@8928: } gernotbelger@8928: catch (final JRException je) { gernotbelger@8928: getLog().warn("Error generating PDF Report!", je); gernotbelger@8928: } gernotbelger@8928: } gernotbelger@8928: gernotbelger@8928: protected abstract String getJasperFile(); gernotbelger@8928: gernotbelger@8928: private JRDataSource createJRData() { gernotbelger@8928: gernotbelger@8928: /* fetch calculation results */ gernotbelger@8928: final RESULTS results = this.data; gernotbelger@8928: gernotbelger@8928: final MetaAndTableJRDataSource source = new MetaAndTableJRDataSource(); gernotbelger@8928: gernotbelger@8928: addJRMetaData(source, results); gernotbelger@8928: gernotbelger@8928: for (final RESULT result : results.getResults()) { gernotbelger@8938: addJRTableData(source, results, result); gernotbelger@8928: } gernotbelger@8928: gernotbelger@8928: return source; gernotbelger@8928: } gernotbelger@8928: gernotbelger@8928: protected abstract void addJRMetaData(final MetaAndTableJRDataSource source, final RESULTS results); gernotbelger@8928: gernotbelger@8938: protected final void addJRTableData(final MetaAndTableJRDataSource source, final RESULTS results, final RESULT result) { gernotbelger@8928: gernotbelger@8928: final Collection rows = result.getRows(); gernotbelger@8928: gernotbelger@8928: for (final ROW row : rows) { gernotbelger@8928: gernotbelger@8938: final String[] formattedRow = formatPDFRow(results, row); gernotbelger@8928: source.addData(formattedRow); gernotbelger@8928: } gernotbelger@8928: } gernotbelger@8928: gernotbelger@8938: protected abstract String[] formatPDFRow(RESULTS results, final ROW row); gernotbelger@8946: gernotbelger@8946: protected final void writeCSVGlobalMetadataDefaults(final CSVWriter writer, final AbstractSInfoCalculationResults results) { gernotbelger@8946: gernotbelger@8946: final String calcModeLabel = results.getCalcModeLabel(); gernotbelger@8946: final RiverInfo river = results.getRiver(); gernotbelger@8946: final DoubleRange calcRange = results.getCalcRange(); gernotbelger@8946: gernotbelger@8946: writeCSVMetaEntry(writer, SInfoI18NStrings.CSV_META_HEADER_RESULT, msg(SInfoI18NStrings.CSV_META_HEADER_RESULT_LABEL), river.getName(), calcModeLabel); gernotbelger@8946: gernotbelger@8946: // "# FLYS-Version: " gernotbelger@8946: writeCSVMetaEntry(writer, SInfoI18NStrings.CSV_META_VERSION, msg(SInfoI18NStrings.CSV_META_VERSION_LABEL), FLYS.VERSION); gernotbelger@8946: gernotbelger@8946: // "# Bearbeiter: " gernotbelger@8946: writeCSVMetaEntry(writer, SInfoI18NStrings.CSV_META_USER, msg(SInfoI18NStrings.CSV_META_USER_LABEL), results.getUser()); gernotbelger@8946: gernotbelger@8946: // "# Datum der Erstellung: " gernotbelger@8946: final Locale locale = Resources.getLocale(this.context.getMeta()); gernotbelger@8946: final DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, locale); gernotbelger@8946: writeCSVMetaEntry(writer, SInfoI18NStrings.CSV_META_CREATION, msg(SInfoI18NStrings.CSV_META_CREATION_LABEL), df.format(new Date())); gernotbelger@8946: gernotbelger@8946: // "# Gewässer: " gernotbelger@8946: writeCSVMetaEntry(writer, SInfoI18NStrings.CSV_META_RIVER, msg(SInfoI18NStrings.CSV_META_RIVER_LABEL), river.getName()); gernotbelger@8946: gernotbelger@8946: // "# Höhensystem des Flusses: " gernotbelger@8946: writeCSVMetaEntry(writer, SInfoI18NStrings.CSV_META_HEIGHT_UNIT_RIVER, river.getWstUnit()); gernotbelger@8946: gernotbelger@8946: // "# Ort/Bereich (km): " gernotbelger@8946: writeCSVMetaEntry(writer, SInfoI18NStrings.CSV_META_RANGE, msg(SInfoI18NStrings.CSV_META_RANGE_LABEL), gernotbelger@8946: getKmFormatter().format(calcRange.getMinimumDouble()), getKmFormatter().format(calcRange.getMaximumDouble())); gernotbelger@8946: } gernotbelger@8946: gernotbelger@8946: protected final void writeCSVSoundingMetadata(final CSVWriter writer, final BedHeightInfo sounding) { gernotbelger@8946: // "##METADATEN PEILUNG" gernotbelger@8946: writeCSVMetaEntry(writer, CSV_META_HEADER_SOUNDING); gernotbelger@8946: gernotbelger@8946: // "# Jahr der Peilung: " gernotbelger@8946: writeCSVMetaEntry(writer, CSV_META_HEADER_SOUNDING_YEAR, Integer.toString(sounding.getYear())); gernotbelger@8946: // "# Aufnahmeart: " gernotbelger@8946: writeCSVMetaEntry(writer, CSV_META_HEADER_SOUNDING_TYPE, sounding.getType()); gernotbelger@8946: // "# Auswerter: " gernotbelger@8946: writeCSVMetaEntry(writer, CSV_META_HEADER_SOUNDING_EVALUATOR, sounding.getEvaluationBy()); gernotbelger@8946: // "# Lagesystem: " gernotbelger@8946: writeCSVMetaEntry(writer, CSV_META_HEADER_SOUNDING_PRJ, sounding.getLocationSystem()); gernotbelger@8946: // "# Höhensystem: " gernotbelger@8946: writeCSVMetaEntry(writer, CSV_META_HEADER_SOUNDING_ELEVATIOIN_MODEL, sounding.getCurElevationModelUnit()); gernotbelger@8946: // "# ursprüngliches Höhensystem: " gernotbelger@8946: writeCSVMetaEntry(writer, CSV_META_HEADER_SOUNDING_ELEVATIOIN_MODEL_ORIGINAL, sounding.getOldElevationModelUnit()); gernotbelger@8946: } gernotbelger@8946: gernotbelger@8946: protected final void writeCSVWaterlevelMetadata(final CSVWriter writer, final WstInfo wst) { gernotbelger@8946: // "##METADATEN WASSERSPIEGELLAGE" gernotbelger@8946: writeCSVMetaEntry(writer, SInfoI18NStrings.CSV_META_HEADER_WATERLEVEL); gernotbelger@8946: gernotbelger@8946: // "# Bezeichnung der Wasserspiegellage: " gernotbelger@8946: writeCSVMetaEntry(writer, SInfoI18NStrings.CSV_META_HEADER_WATERLEVEL_NAME, wst.getLabel()); gernotbelger@8946: gernotbelger@8946: // "# Bezugspegel: " gernotbelger@8946: writeCSVMetaEntry(writer, SInfoI18NStrings.CSV_META_HEADER_WATERLEVEL_GAUGE, wst.getGauge()); gernotbelger@8946: gernotbelger@8946: // "# Jahr/Zeitraum der Wasserspiegellage: " gernotbelger@8946: final int year = wst.getYear(); gernotbelger@8946: if (year > 0) gernotbelger@8946: writeCSVMetaEntry(writer, SInfoI18NStrings.CSV_META_HEADER_WATERLEVEL_YEAR, Integer.toString(year)); gernotbelger@8946: } gernotbelger@8946: gernotbelger@8946: protected final void addJRMetaDataDefaults(final MetaAndTableJRDataSource source, final AbstractSInfoCalculationResults results) { gernotbelger@8946: gernotbelger@8946: final RiverInfo river = results.getRiver(); gernotbelger@8946: final String wstUnitName = river.getWstUnit(); gernotbelger@8946: gernotbelger@8946: source.addMetaData("header", msg(SInfoI18NStrings.CSV_META_HEADER_RESULT_LABEL)); gernotbelger@8946: source.addMetaData("calcMode", results.getCalcModeLabel()); gernotbelger@8946: gernotbelger@8946: source.addMetaData("version_label", msg(SInfoI18NStrings.CSV_META_VERSION_LABEL)); gernotbelger@8946: source.addMetaData("version", FLYS.VERSION); gernotbelger@8946: gernotbelger@8946: source.addMetaData("user_label", msg(SInfoI18NStrings.CSV_META_USER_LABEL)); gernotbelger@8946: source.addMetaData("user", results.getUser()); gernotbelger@8946: gernotbelger@8946: final Locale locale = Resources.getLocale(this.context.getMeta()); gernotbelger@8946: final DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, locale); gernotbelger@8946: source.addMetaData("date_label", msg(SInfoI18NStrings.CSV_META_CREATION_LABEL)); gernotbelger@8946: source.addMetaData("date", df.format(new Date())); gernotbelger@8946: gernotbelger@8946: source.addMetaData("river_label", msg(SInfoI18NStrings.CSV_META_RIVER_LABEL)); gernotbelger@8946: source.addMetaData("river", river.getName()); gernotbelger@8946: source.addMetaData("river_unit", wstUnitName); gernotbelger@8946: gernotbelger@8946: final DoubleRange calcRange = results.getCalcRange(); gernotbelger@8946: final NumberFormat kmFormatter = getKmFormatter(); gernotbelger@8946: final String rangeValue = String.format("%s - %s", kmFormatter.format(calcRange.getMinimumDouble()), kmFormatter.format(calcRange.getMaximumDouble())); gernotbelger@8946: source.addMetaData("range_label", msg(SInfoI18NStrings.CSV_META_RANGE_LABEL)); gernotbelger@8946: source.addMetaData("range", rangeValue); gernotbelger@8946: } gernotbelger@8928: }