andre@8578: /* Copyright (C) 2011, 2012, 2013, 2015 by Bundesanstalt für Gewässerkunde teichmann@5863: * Software engineering by Intevation GmbH teichmann@5863: * teichmann@5994: * This file is Free Software under the GNU AGPL (>=v3) teichmann@5863: * and comes with ABSOLUTELY NO WARRANTY! Check out the teichmann@5994: * documentation coming with Dive4Elements River for details. teichmann@5863: */ teichmann@5863: teichmann@5831: package org.dive4elements.river.exports.sq; ingo@3077: ingo@3077: import java.io.OutputStream; ingo@3077: import java.util.ArrayList; ingo@3077: import java.util.List; aheinecke@6172: import java.util.Map; aheinecke@6172: import java.util.HashMap; aheinecke@6172: import java.util.Date; aheinecke@6172: import java.util.Locale; aheinecke@6172: import java.text.DateFormat; aheinecke@6828: import java.text.NumberFormat; ingo@3077: aheinecke@6172: import net.sf.jasperreports.engine.JasperExportManager; aheinecke@6172: import net.sf.jasperreports.engine.JasperFillManager; aheinecke@6172: import net.sf.jasperreports.engine.JasperPrint; andre@8578: import net.sf.jasperreports.engine.JRPrintPage; aheinecke@6172: import net.sf.jasperreports.engine.JRException; aheinecke@6172: ingo@3077: import au.com.bytecode.opencsv.CSVWriter; ingo@3077: aheinecke@6172: import org.dive4elements.artifacts.CallMeta; sascha@3392: teichmann@5831: import org.dive4elements.river.artifacts.model.CalculationResult; teichmann@5831: import org.dive4elements.river.artifacts.model.sq.SQFractionResult; teichmann@5831: import org.dive4elements.river.artifacts.model.sq.SQResult; andre@8541: import org.dive4elements.river.artifacts.model.sq.SQ; aheinecke@6172: import org.dive4elements.river.artifacts.model.sq.SQRelationJRDataSource; andre@8578: import org.dive4elements.river.artifacts.model.sq.SQMeasurementsJRDataSource; teichmann@5831: import org.dive4elements.river.artifacts.model.Parameters; aheinecke@6172: import org.dive4elements.river.artifacts.model.DateRange; aheinecke@6172: import org.dive4elements.river.artifacts.access.SQRelationAccess; aheinecke@6172: aheinecke@6172: import org.dive4elements.river.artifacts.resources.Resources; aheinecke@6172: aheinecke@6172: import org.dive4elements.river.artifacts.D4EArtifact; teichmann@5831: teichmann@5831: import org.dive4elements.river.exports.AbstractExporter; ingo@3077: aheinecke@6172: import org.dive4elements.river.utils.RiverUtils; aheinecke@6172: import org.dive4elements.river.utils.Formatter; aheinecke@6172: aheinecke@6172: import org.dive4elements.artifacts.common.utils.Config; aheinecke@6172: sascha@3392: import org.apache.log4j.Logger; ingo@3077: ingo@3077: /** ingo@3077: * @author Ingo Weinzierl ingo@3077: */ ingo@3077: public class SQRelationExporter extends AbstractExporter { ingo@3077: teichmann@8202: /** Private log. */ teichmann@8202: private static final Logger log = ingo@3077: Logger.getLogger(SQRelationExporter.class); ingo@3077: tom@7937: public static final String INFO_COEFF_A = tom@7937: "export.sqrelation.csv.info.coeff.a"; tom@7937: tom@7937: public static final String INFO_COEFF_B = tom@7937: "export.sqrelation.csv.info.coeff.b"; tom@7937: tom@7937: public static final String INFO_QMAX = tom@7937: "export.sqrelation.csv.info.qmax"; tom@7937: tom@7965: public static final String INFO_STDERR = tom@7965: "export.sqrelation.csv.info.stderr"; tom@7965: tom@7937: public static final String INFO_R2 = tom@7937: "export.sqrelation.csv.info.r2"; tom@7937: tom@7937: public static final String INFO_NTOT = tom@7937: "export.sqrelation.csv.info.ntot"; tom@7937: tom@7937: public static final String INFO_NOUTL = tom@7937: "export.sqrelation.csv.info.noutl"; tom@7937: tom@7937: public static final String INFO_CFERGUSON = tom@7937: "export.sqrelation.csv.info.cferguson"; tom@7937: tom@7937: public static final String INFO_CDUAN = tom@7937: "export.sqrelation.csv.info.cduan"; tom@7937: tom@7937: public static final String INFO_PARAM_A = tom@7937: "export.sqrelation.csv.info.param.a"; tom@7937: tom@7937: public static final String INFO_PARAM_B = tom@7937: "export.sqrelation.csv.info.param.b"; tom@7937: tom@7937: public static final String INFO_PARAM_C = tom@7937: "export.sqrelation.csv.info.param.c"; tom@7937: tom@7937: public static final String INFO_PARAM_D = tom@7937: "export.sqrelation.csv.info.param.d"; tom@7937: tom@7937: public static final String INFO_PARAM_E = tom@7937: "export.sqrelation.csv.info.param.e"; tom@7937: tom@7937: public static final String INFO_PARAM_F = tom@7937: "export.sqrelation.csv.info.param.f"; ingo@3077: andre@8541: public static final String INFO_Q = andre@8541: "export.sqrelation.csv.info.q"; andre@8541: andre@8541: public static final String INFO_S_KG = andre@8541: "export.sqrelation.csv.info.s_kg"; andre@8541: andre@8541: public static final String INFO_DATE = andre@8541: "export.sqrelation.csv.info.date"; andre@8541: ingo@3077: public static final String CSV_PARAMETER = ingo@3077: "export.sqrelation.csv.header.parameter"; ingo@3077: ingo@3077: public static final String CSV_STATION = ingo@3077: "export.sqrelation.csv.header.station"; ingo@3077: ingo@3077: public static final String CSV_KM = ingo@3077: "export.sqrelation.csv.header.km"; ingo@3077: ingo@3077: public static final String CSV_FUNCTION = ingo@3077: "export.sqrelation.csv.header.function"; ingo@3077: ingo@3077: public static final String CSV_GAUGE = ingo@3077: "export.sqrelation.csv.header.gauge"; ingo@3077: ingo@3077: public static final String CSV_COEFF_A = ingo@3077: "export.sqrelation.csv.header.coeff.a"; ingo@3077: ingo@3077: public static final String CSV_COEFF_B = ingo@3077: "export.sqrelation.csv.header.coeff.b"; ingo@3077: ingo@3077: public static final String CSV_COEFF_Q = ingo@3077: "export.sqrelation.csv.header.coeff.q"; ingo@3077: ingo@3077: public static final String CSV_COEFF_R = ingo@3077: "export.sqrelation.csv.header.coeff.r"; ingo@3077: ingo@3077: public static final String CSV_N_TOTAL = ingo@3077: "export.sqrelation.csv.header.n.total"; ingo@3077: ingo@3077: public static final String CSV_N_OUTLIERS = ingo@3077: "export.sqrelation.csv.header.n.outliers"; ingo@3077: ingo@3077: public static final String CSV_C_DUAN = ingo@3077: "export.sqrelation.csv.header.c.duan"; ingo@3077: ingo@3077: public static final String CSV_C_FERGUSON = ingo@3077: "export.sqrelation.csv.header.c.ferguson"; ingo@3077: aheinecke@6828: public static final String CSV_QMAX = aheinecke@6828: "export.sqrelation.csv.header.qmax"; aheinecke@6828: aheinecke@6828: public static final String CSV_SD = aheinecke@6828: "export.sqrelation.csv.header.sd"; ingo@3077: andre@8541: public static final String CSV_S_KG = andre@8541: "export.sqrelation.csv.header.s_kg"; andre@8541: andre@8541: public static final String CSV_Q = andre@8541: "export.sqrelation.csv.header.q"; andre@8541: andre@8541: public static final String CSV_DATE = andre@8541: "export.sqrelation.csv.header.date"; andre@8541: aheinecke@6172: public static final String PDF_TITLE= aheinecke@6172: "export.sqrelation.pdf.title"; aheinecke@6172: aheinecke@6172: public static final String PDF_HEADER_MODE = aheinecke@6172: "export.sqrelation.pdf.mode"; aheinecke@6172: aheinecke@6172: public static final String JASPER_FILE = aheinecke@6172: "export.sqrelation.pdf.file"; ingo@3077: andre@8578: public static final String JASPER_MEASUREMENTS_FILE = andre@8578: "export.sqrelation.measurements.pdf.file"; andre@8578: sascha@3392: protected List data; ingo@3077: teichmann@7077: public SQRelationExporter() { sascha@3392: data = new ArrayList(); ingo@3077: } ingo@3077: ingo@3077: @Override ingo@3077: protected void addData(Object d) { ingo@3077: if (d instanceof CalculationResult) { sascha@3392: d = ((CalculationResult)d).getData(); sascha@3392: if (d instanceof SQResult []) { sascha@3392: data.add((SQResult [])d); ingo@3077: } ingo@3077: } ingo@3077: } ingo@3077: sascha@3392: protected void writeCSVHeader(CSVWriter writer) { sascha@3392: writer.writeNext(new String[] { tom@7936: msg(CSV_KM), tom@7936: msg(CSV_PARAMETER), tom@7936: msg(CSV_COEFF_A), tom@7936: msg(CSV_COEFF_B), tom@7936: msg(CSV_SD), tom@7936: msg(CSV_QMAX), tom@7936: msg(CSV_COEFF_R), tom@7936: msg(CSV_N_TOTAL), tom@7936: msg(CSV_N_OUTLIERS), tom@7936: msg(CSV_C_DUAN), andre@8541: msg(CSV_C_FERGUSON), andre@8541: msg(CSV_S_KG), andre@8541: msg(CSV_Q), andre@8541: msg(CSV_DATE) sascha@3392: }); sascha@3392: } ingo@3077: ingo@3077: @Override ingo@3077: protected void writeCSVData(CSVWriter writer) { teichmann@8202: log.debug("writeCSVData"); ingo@3077: tom@7937: writeCSVInfo(writer, new String[] { tom@7937: msg(INFO_COEFF_A), tom@7937: msg(INFO_COEFF_B), tom@7937: msg(INFO_QMAX), tom@7965: msg(INFO_STDERR), tom@7937: msg(INFO_R2), tom@7937: msg(INFO_NTOT), tom@7937: msg(INFO_NOUTL), tom@7937: msg(INFO_CFERGUSON), tom@7937: msg(INFO_CDUAN), tom@7937: msg(INFO_PARAM_A), tom@7937: msg(INFO_PARAM_B), tom@7937: msg(INFO_PARAM_C), tom@7937: msg(INFO_PARAM_D), tom@7937: msg(INFO_PARAM_E), andre@8541: msg(INFO_PARAM_F), andre@8541: msg(INFO_S_KG), andre@8541: msg(INFO_Q), andre@8541: msg(INFO_DATE) tom@7937: }); tom@7937: ingo@3077: writeCSVHeader(writer); ingo@3077: sascha@3392: for (SQResult [] results: data) { sascha@3392: for (SQResult result: results) { andre@8578: writer.writeAll(data2StringArrays(result, true)); sascha@3392: } ingo@3077: } ingo@3077: } ingo@3077: andre@8578: protected List data2StringArrays(SQResult result, boolean includeMeasurements) { aheinecke@6322: String km = Formatter.getSQRelationKM(context aheinecke@6322: ).format(result.getKm()); aheinecke@6172: List retval = new ArrayList(); ingo@3077: aheinecke@6828: NumberFormat sqAFormatter = Formatter.getSQRelationA(context); aheinecke@6828: NumberFormat sqBFormatter = Formatter.getSQRelationB(context); aheinecke@6828: NumberFormat fThreeFormatter = Formatter.getFormatter(context, 3, 3); aheinecke@6828: NumberFormat fTwoFormatter = Formatter.getFormatter(context, 2, 2); aheinecke@6828: NumberFormat fZeroFormatter = Formatter.getFormatter(context, 0, 0); andre@8541: DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, andre@8541: Resources.getLocale(context.getMeta())); aheinecke@6828: sascha@3392: for (int i = 0; i < SQResult.NUMBER_FRACTIONS; ++i) { sascha@3392: SQFractionResult fraction = result.getFraction(i); sascha@3552: sascha@3552: String name = result.getFractionName(i); sascha@3552: sascha@3552: Parameters parameters = fraction.getParameters(); sascha@3552: sascha@3552: if (parameters == null) { sascha@3392: continue; sascha@3392: } sascha@3552: aheinecke@6828: String a, b, sd, o, t, max_q, c_ferguson, c_duan, r2; aheinecke@6828: a = sqAFormatter.format(parameters.getValue(0, "a")); aheinecke@6828: b = sqBFormatter.format(parameters.getValue(0, "b")); aheinecke@6828: aheinecke@6828: /* The std_dev parameter contains the standard error actually */ aheinecke@6828: sd = fThreeFormatter.format(parameters.getValue(0, "std_dev")); aheinecke@6828: max_q = fZeroFormatter.format(parameters.getValue(0, "max_q")); aheinecke@6828: c_ferguson = fTwoFormatter.format(parameters.getValue(0, "c_ferguson")); aheinecke@6828: c_duan = fTwoFormatter.format(parameters.getValue(0, "c_duan")); aheinecke@6828: r2 = fTwoFormatter.format(parameters.getValue(0, "r2")); aheinecke@6828: sascha@3552: aheinecke@6172: o = String.valueOf(fraction.totalNumOutliers()); teichmann@7640: t = String.valueOf(fraction.numMeasurements()); aheinecke@6172: andre@8578: if (includeMeasurements) { andre@8578: for (SQ sq: fraction.getMeasurements()) { andre@8578: retval.add(new String[] { andre@8578: km, andre@8578: name, andre@8578: a, andre@8578: b, andre@8578: sd, // 4 andre@8578: max_q, // 5 andre@8578: r2, // 6 andre@8578: t, // 7 andre@8578: o, // 8 andre@8578: c_duan, // 9 andre@8578: c_ferguson, // 10 andre@8630: fThreeFormatter.format(sq.getS()), andre@8578: fZeroFormatter.format(sq.getQ()), andre@8578: df.format(sq.getDate()) andre@8578: }); andre@8578: } andre@8578: } else { andre@8541: retval.add(new String[] { andre@8541: km, andre@8541: name, andre@8541: a, andre@8541: b, andre@8541: sd, // 4 andre@8541: max_q, // 5 andre@8541: r2, // 6 andre@8541: t, // 7 andre@8541: o, // 8 andre@8541: c_duan, // 9 andre@8578: c_ferguson // 10 andre@8541: }); andre@8541: } andre@8541: sascha@3392: } aheinecke@6172: return retval; ingo@3077: } ingo@3077: ingo@3077: aheinecke@6172: protected SQRelationJRDataSource createJRData() { aheinecke@6172: SQRelationJRDataSource source = new SQRelationJRDataSource(); aheinecke@6172: aheinecke@6172: addMetaData(source); aheinecke@6172: for (SQResult [] results: data) { aheinecke@6172: for (SQResult result: results) { andre@8578: for (String[] res: data2StringArrays(result, false)) { aheinecke@6172: source.addData(res); aheinecke@6172: } aheinecke@6172: } aheinecke@6172: } aheinecke@6172: return source; aheinecke@6172: } aheinecke@6172: andre@8578: protected SQMeasurementsJRDataSource createMeasurementJRData() { andre@8578: SQMeasurementsJRDataSource source = new SQMeasurementsJRDataSource(); andre@8578: NumberFormat fZeroFormatter = Formatter.getFormatter(context, 0, 0); andre@8630: NumberFormat fThreeFormatter = Formatter.getFormatter(context, 3, 3); andre@8578: DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, andre@8578: Resources.getLocale(context.getMeta())); andre@8578: andre@8578: for (SQResult [] results: data) { andre@8578: for (SQResult result: results) { andre@8578: for (int i = 0; i < SQResult.NUMBER_FRACTIONS; ++i) { andre@8578: String name = result.getFractionName(i); andre@8578: SQFractionResult fraction = result.getFraction(i); andre@8578: for (SQ sq: fraction.getMeasurements()) { andre@8578: source.addData(new String[] { andre@8578: name, andre@8630: fThreeFormatter.format(sq.getS()), andre@8578: fZeroFormatter.format(sq.getQ()), andre@8578: df.format(sq.getDate()), andre@8578: null andre@8578: }); andre@8578: } andre@8578: for (int j = 0; j < fraction.numIterations(); j++) { andre@8578: for (SQ sq: fraction.getOutliers(j)) { andre@8578: source.addData(new String[] { andre@8578: name, andre@8630: fThreeFormatter.format(sq.getS()), andre@8578: fZeroFormatter.format(sq.getQ()), andre@8578: df.format(sq.getDate()), andre@8578: Integer.toString(j + 1) andre@8578: }); andre@8578: } andre@8578: } andre@8578: } andre@8578: } andre@8578: } andre@8578: return source; andre@8578: } andre@8578: aheinecke@6172: protected void addMetaData(SQRelationJRDataSource source) { aheinecke@6172: CallMeta meta = context.getMeta(); aheinecke@6172: aheinecke@6172: D4EArtifact arti = (D4EArtifact) master; aheinecke@6172: aheinecke@6172: source.addMetaData ("river", RiverUtils.getRivername(arti)); aheinecke@6172: aheinecke@6172: Locale locale = Resources.getLocale(meta); aheinecke@6172: DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, locale); aheinecke@6172: aheinecke@6172: source.addMetaData("date", df.format(new Date())); aheinecke@6172: aheinecke@6172: SQRelationAccess access = new SQRelationAccess(arti); aheinecke@6175: source.addMetaData("location", "KM " + getKmFormatter().format(access.getLocation())); aheinecke@6172: aheinecke@6172: DateRange period = access.getPeriod(); aheinecke@6172: source.addMetaData("periods", df.format(period.getFrom()) + " - " + aheinecke@6172: df.format(period.getTo())); aheinecke@6172: aheinecke@6175: source.addMetaData("outliertest", Resources.getMsg(meta, aheinecke@6175: access.getOutlierMethod(), aheinecke@6175: access.getOutlierMethod())); aheinecke@6830: source.addMetaData("outliers", Formatter.getRawFormatter(context).format( aheinecke@6830: access.getOutliers())); aheinecke@6172: aheinecke@6172: source.addMetaData("calculation", Resources.getMsg( aheinecke@6172: locale, aheinecke@6172: PDF_HEADER_MODE, aheinecke@6172: "SQRelation")); aheinecke@6859: aheinecke@6859: String measurementStationName = access.getMeasurementStationName(); aheinecke@6859: aheinecke@6859: if (measurementStationName != null) { aheinecke@6859: source.addMetaData("msName", measurementStationName); aheinecke@7380: } else { aheinecke@7380: source.addMetaData("msName", ""); aheinecke@6859: } aheinecke@6859: aheinecke@6859: String measurementStationGaugeName = access.getMeasurementStationGaugeName(); aheinecke@6859: aheinecke@6859: if (measurementStationGaugeName != null) { aheinecke@6859: source.addMetaData("msGauge", measurementStationGaugeName); aheinecke@7380: } else { aheinecke@7380: source.addMetaData("msGauge", ""); aheinecke@6859: } aheinecke@6859: aheinecke@6172: } aheinecke@6172: ingo@3077: @Override ingo@3077: protected void writePDF(OutputStream out) { teichmann@8202: log.debug("write PDF"); aheinecke@6172: SQRelationJRDataSource source = createJRData(); andre@8578: SQMeasurementsJRDataSource measureSource = createMeasurementJRData(); aheinecke@6172: aheinecke@6172: String jasperFile = Resources.getMsg( andre@8578: context.getMeta(), andre@8578: JASPER_FILE, andre@8578: "/jasper/sqrelation_en.jasper"); andre@8578: String jasperMeasurementsFile = Resources.getMsg( andre@8578: context.getMeta(), andre@8578: JASPER_MEASUREMENTS_FILE, andre@8578: "/jasper/sqmeasurements_en.jasper"); aheinecke@6172: String confPath = Config.getConfigDirectory().toString(); aheinecke@6172: aheinecke@6172: aheinecke@6172: Map parameters = new HashMap(); aheinecke@6172: parameters.put("ReportTitle", Resources.getMsg( aheinecke@6172: context.getMeta(), PDF_TITLE, "Exported Data")); aheinecke@6172: try { andre@8578: /* Page numbers start have a built in offset of 1 so this andre@8578: * is fine. */ andre@8578: JasperPrint p2 = JasperFillManager.fillReport( andre@8578: confPath + jasperMeasurementsFile, andre@8578: parameters, andre@8578: measureSource); andre@8578: parameters.put("MEASUREMENT_PAGE_NUM", p2.getPages().size()); andre@8578: JasperPrint p1 = JasperFillManager.fillReport( aheinecke@6172: confPath + jasperFile, aheinecke@6172: parameters, aheinecke@6172: source); andre@8578: for (Object page: p2.getPages()) { andre@8578: JRPrintPage object = (JRPrintPage)page; andre@8578: p1.addPage(object); andre@8578: } andre@8578: JasperExportManager.exportReportToPdfStream(p1, out); aheinecke@6172: } aheinecke@6172: catch(JRException je) { teichmann@8202: log.warn("Error generating PDF Report!", je); aheinecke@6172: } ingo@3077: } ingo@3077: } ingo@3077: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :