gernotbelger@8999: /** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde gernotbelger@8999: * Software engineering by gernotbelger@8999: * Björnsen Beratende Ingenieure GmbH gernotbelger@8999: * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt gernotbelger@8999: * gernotbelger@8999: * This file is Free Software under the GNU AGPL (>=v3) gernotbelger@8999: * and comes with ABSOLUTELY NO WARRANTY! Check out the gernotbelger@8999: * documentation coming with Dive4Elements River for details. gernotbelger@8999: */ gernotbelger@8999: package org.dive4elements.river.artifacts.common; gernotbelger@8999: gernotbelger@8999: import java.io.OutputStream; gernotbelger@8999: import java.util.Collection; gernotbelger@8999: import java.util.HashMap; gernotbelger@8999: import java.util.List; gernotbelger@8999: import java.util.Map; gernotbelger@8999: gernotbelger@8999: import org.apache.log4j.Logger; gernotbelger@8999: import org.dive4elements.artifacts.CallMeta; gernotbelger@8999: import org.dive4elements.artifacts.common.utils.Config; gernotbelger@8999: import org.dive4elements.river.artifacts.model.CalculationResult; gernotbelger@8999: import org.dive4elements.river.artifacts.resources.Resources; gernotbelger@8999: import org.dive4elements.river.artifacts.sinfo.util.MetaAndTableJRDataSource; gernotbelger@8999: import org.dive4elements.river.artifacts.sinfo.util.RiverInfo; gernotbelger@8999: import org.dive4elements.river.exports.AbstractExporter; gernotbelger@8999: gernotbelger@8999: import au.com.bytecode.opencsv.CSVWriter; gernotbelger@8999: import net.sf.jasperreports.engine.JRDataSource; gernotbelger@8999: import net.sf.jasperreports.engine.JRElement; gernotbelger@8999: import net.sf.jasperreports.engine.JRException; gernotbelger@8999: import net.sf.jasperreports.engine.JRPrintPage; gernotbelger@8999: import net.sf.jasperreports.engine.JasperCompileManager; gernotbelger@8999: import net.sf.jasperreports.engine.JasperExportManager; gernotbelger@8999: import net.sf.jasperreports.engine.JasperFillManager; gernotbelger@8999: import net.sf.jasperreports.engine.JasperPrint; gernotbelger@8999: import net.sf.jasperreports.engine.JasperReport; gernotbelger@8999: import net.sf.jasperreports.engine.design.JasperDesign; gernotbelger@8999: import net.sf.jasperreports.engine.util.JRProperties; gernotbelger@8999: import net.sf.jasperreports.engine.xml.JRSaxParserFactory; gernotbelger@8999: import net.sf.jasperreports.engine.xml.JRXmlLoader; gernotbelger@8999: gernotbelger@8999: /** gernotbelger@8999: * @author Gernot Belger gernotbelger@8999: */ gernotbelger@8999: public abstract class AbstractCommonExporter> extends AbstractExporter { gernotbelger@8999: gernotbelger@8999: /** The storage that contains the current calculation result. */ gernotbelger@8999: protected static enum ExportMode { gernotbelger@8999: pdf, csv gernotbelger@8999: } gernotbelger@8999: gernotbelger@8999: /** The log used in this exporter. */ gernotbelger@8999: protected abstract Logger getLog(); gernotbelger@8999: gernotbelger@8999: protected RESULTS data = null; gernotbelger@8999: gernotbelger@8999: public RESULTS getData() { gernotbelger@8999: return this.data; gernotbelger@8999: } gernotbelger@8999: gernotbelger@8999: @Override gernotbelger@8999: protected void addData(final Object d) { gernotbelger@8999: /* reset */ gernotbelger@8999: this.data = null; gernotbelger@8999: gernotbelger@8999: if (d instanceof CalculationResult) { gernotbelger@8999: gernotbelger@8999: final Object dat = ((CalculationResult) d).getData(); gernotbelger@8999: if (dat != null) { gernotbelger@8999: @SuppressWarnings("unchecked") gernotbelger@8999: final RESULTS result = (RESULTS) dat; gernotbelger@8999: this.data = result; gernotbelger@8999: } gernotbelger@8999: } gernotbelger@8999: } gernotbelger@8999: gernotbelger@8999: /** gernotbelger@8999: * Formats header with unit and label: msg [unit] (label) gernotbelger@8999: */ gernotbelger@8999: protected String msgUnitLabel(final String key, final String unit, final String label) { gernotbelger@8999: final String msg = msg(key); gernotbelger@8999: return String.format("%s [%s] (%s)", msg, unit, label); gernotbelger@8999: } gernotbelger@8999: gernotbelger@8999: @Override gernotbelger@8999: protected void writeCSVData(final CSVWriter writer) { gernotbelger@8999: getLog().info("writeCSVData"); gernotbelger@8999: gernotbelger@8999: /* fetch calculation results */ gernotbelger@8999: final RESULTS results = this.data; gernotbelger@8999: gernotbelger@8999: /* write as csv */ gernotbelger@8999: writeCSVGlobalMetadata(writer, results); gernotbelger@8999: writer.writeNext(new String[] { "" }); // break line HERE to avoid redundance gernotbelger@8999: final RiverInfo river = results.getRiver(); gernotbelger@8999: // FIXME :with comment if not first result gernotbelger@8999: writeCSVHeader(writer, results, river); gernotbelger@8999: writer.writeNext(new String[] { "" }); // break line HERE to avoid redundance gernotbelger@8999: gernotbelger@8999: for (final RESULT result : results.getResults()) { gernotbelger@8999: writeCSVResult(writer, results, result); gernotbelger@8999: writer.writeNext(new String[] { "" }); // break line HERE after each resultset gernotbelger@8999: } gernotbelger@8999: gernotbelger@8999: } gernotbelger@8999: gernotbelger@8999: protected abstract void writeCSVHeader(final CSVWriter writer, final RESULTS results, final RiverInfo river); gernotbelger@8999: gernotbelger@8999: /** gernotbelger@8999: * Add metadata that is once written to the top of the file. gernotbelger@8999: */ gernotbelger@8999: protected abstract void writeCSVGlobalMetadata(final CSVWriter writer, final RESULTS results); gernotbelger@8999: gernotbelger@8999: protected void writeCSVMetaEntry(final CSVWriter writer, final String message, final Object... messageArgs) { gernotbelger@8999: gernotbelger@8999: final CallMeta meta = this.context.getMeta(); gernotbelger@8999: gernotbelger@8999: writer.writeNext(new String[] { Resources.getMsg(meta, message, message, messageArgs) }); gernotbelger@8999: } gernotbelger@8999: gernotbelger@8999: private void writeCSVResult(final CSVWriter writer, final RESULTS results, final RESULT result) { gernotbelger@8999: gernotbelger@8999: writeCSVResultMetadata(writer, results, result); gernotbelger@8999: writer.writeNext(new String[] { "" }); // break line HERE to avoid redundance gernotbelger@8999: gernotbelger@8999: // final RiverInfo river = results.getRiver(); gernotbelger@8999: // gernotbelger@8999: // writeCSVHeader(writer, results, river); gernotbelger@8999: /* now the value rows */ gernotbelger@8999: final Collection rows = result.getRows(); // war mal SInfoResultRow gernotbelger@8999: for (final ResultRow row : rows) { gernotbelger@8999: writeCSVRow(writer, results, result, row); gernotbelger@8999: } gernotbelger@8999: } gernotbelger@8999: gernotbelger@8999: /** gernotbelger@8999: * Add metadata that is written once per result set. gernotbelger@8999: */ gernotbelger@8999: protected abstract void writeCSVResultMetadata(CSVWriter writer, RESULTS results, RESULT result); gernotbelger@8999: gernotbelger@8999: protected void writeCSVRow(final CSVWriter writer, final RESULTS results, final RESULT result, final ResultRow row) { gernotbelger@8999: getLog().debug("writeCSVFlowDepthRow"); gernotbelger@8999: gernotbelger@8999: final String[] formattedRow = formatCSVRow(results, row); gernotbelger@8999: writer.writeNext(formattedRow); gernotbelger@8999: } gernotbelger@8999: gernotbelger@8999: protected final String[] formatCSVRow(final RESULTS results, final ResultRow row) { gernotbelger@8999: return formatRow(results, row, ExportMode.csv); gernotbelger@8999: } gernotbelger@8999: gernotbelger@8999: // protected abstract void tweakDesign() gernotbelger@8999: gernotbelger@8999: @Override gernotbelger@8999: protected void writePDF(final OutputStream outStream) { gernotbelger@8999: getLog().debug("write PDF"); gernotbelger@8999: gernotbelger@8999: final JRDataSource source = createJRData(); gernotbelger@8999: final JRDataSource source2 = createJRData(); gernotbelger@8999: gernotbelger@8999: final String confPath = Config.getConfigDirectory().toString(); gernotbelger@8999: gernotbelger@8999: // FIXME: distinguish between with and without tkh: we need two jasper reports! gernotbelger@8999: gernotbelger@8999: final Map parameters = new HashMap<>(); gernotbelger@8999: parameters.put("ReportTitle", "Exported Data"); gernotbelger@8999: gernotbelger@8999: try { gernotbelger@8999: gernotbelger@8999: // JRProperties.setProperty(JRProperties.COMPILER_XML_VALIDATION, false); gernotbelger@8999: JRProperties.setProperty(JRSaxParserFactory.PROPERTY_REPORT_PARSER_FACTORY, JRReportSaxParserFactory.class.getName()); gernotbelger@8999: gernotbelger@8999: final String jasperPath = confPath + getJasperFile(); gernotbelger@8999: final JasperDesign test = JRXmlLoader.load(jasperPath); gernotbelger@8999: gernotbelger@8999: final JRElement element = test.getColumnHeader().getElementByKey("TEST"); gernotbelger@8999: // element.setWidth(200); gernotbelger@8999: gernotbelger@8999: final JasperReport compiled = JasperCompileManager.compileReport(test); gernotbelger@8999: gernotbelger@8999: final JasperPrint print = JasperFillManager.fillReport(compiled, parameters, source); gernotbelger@8999: // JasperExportManager.exportReportToPdfStream(print, outStream); gernotbelger@8999: gernotbelger@8999: final JasperPrint print2 = JasperFillManager.fillReport(compiled, parameters, source2); gernotbelger@8999: gernotbelger@8999: final List pages = print2.getPages(); gernotbelger@8999: for (final JRPrintPage page : pages) gernotbelger@8999: print.addPage(page); gernotbelger@8999: gernotbelger@8999: JasperExportManager.exportReportToPdfStream(print, outStream); gernotbelger@8999: } gernotbelger@8999: catch (final JRException je) { gernotbelger@8999: getLog().warn("Error generating PDF Report!", je); gernotbelger@8999: } gernotbelger@8999: } gernotbelger@8999: gernotbelger@8999: protected abstract String getJasperFile(); gernotbelger@8999: gernotbelger@8999: private JRDataSource createJRData() { gernotbelger@8999: gernotbelger@8999: /* fetch calculation results */ gernotbelger@8999: final RESULTS results = this.data; gernotbelger@8999: gernotbelger@8999: final MetaAndTableJRDataSource source = new MetaAndTableJRDataSource(); gernotbelger@8999: gernotbelger@8999: addJRMetaData(source, results); gernotbelger@8999: gernotbelger@8999: for (final RESULT result : results.getResults()) { gernotbelger@8999: addJRTableData(source, results, result); gernotbelger@8999: } gernotbelger@8999: gernotbelger@8999: return source; gernotbelger@8999: } gernotbelger@8999: gernotbelger@8999: protected abstract void addJRMetaData(final MetaAndTableJRDataSource source, final RESULTS results); gernotbelger@8999: gernotbelger@8999: protected void addJRTableData(final MetaAndTableJRDataSource source, final RESULTS results, final RESULT result) { gernotbelger@8999: gernotbelger@8999: final Collection rows = result.getRows(); gernotbelger@8999: gernotbelger@8999: for (final ResultRow row : rows) { gernotbelger@8999: gernotbelger@8999: final String[] formattedRow = formatPDFRow(results, row); gernotbelger@8999: source.addData(formattedRow); gernotbelger@8999: } gernotbelger@8999: } gernotbelger@8999: gernotbelger@8999: protected abstract String[] formatRow(RESULTS results, ResultRow row, ExportMode mode); gernotbelger@8999: gernotbelger@8999: protected final String[] formatPDFRow(final RESULTS results, final ResultRow row) { gernotbelger@8999: // @Override gernotbelger@8999: // protected String[] formatPDFRow(final FlowDepthDevelopmentCalculationResults results, final ResultRow row) { gernotbelger@8999: return formatRow(results, row, ExportMode.pdf); gernotbelger@8999: // } gernotbelger@8999: } gernotbelger@8999: gernotbelger@8999: protected abstract void writeCSVGlobalMetadataDefaults(final CSVWriter writer, final RESULTS results); gernotbelger@8999: gernotbelger@8999: protected abstract void addJRMetaDataDefaults(final MetaAndTableJRDataSource source, final RESULTS results); gernotbelger@8999: }