gernotbelger@8948: /** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde gernotbelger@8948: * Software engineering by gernotbelger@8948: * Björnsen Beratende Ingenieure GmbH gernotbelger@8948: * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt gernotbelger@8948: * gernotbelger@8948: * This file is Free Software under the GNU AGPL (>=v3) gernotbelger@8948: * and comes with ABSOLUTELY NO WARRANTY! Check out the gernotbelger@8948: * documentation coming with Dive4Elements River for details. gernotbelger@8948: */ gernotbelger@8948: package org.dive4elements.river.artifacts.sinfo.common; gernotbelger@8948: gernotbelger@8948: import java.text.NumberFormat; gernotbelger@8948: import java.util.HashMap; gernotbelger@8948: import java.util.Locale; gernotbelger@8948: import java.util.Map; gernotbelger@8948: gernotbelger@8948: import org.apache.commons.lang.StringUtils; gernotbelger@8948: import org.dive4elements.artifacts.CallContext; gernotbelger@8948: import org.dive4elements.artifacts.CallMeta; gernotbelger@8948: import org.dive4elements.river.artifacts.resources.Resources; gernotbelger@8948: import org.dive4elements.river.artifacts.sinfo.SInfoI18NStrings; gernotbelger@8948: import org.dive4elements.river.artifacts.sinfo.tkhcalculation.SoilKind; gernotbelger@8948: import org.dive4elements.river.utils.Formatter; gernotbelger@8948: import org.dive4elements.river.utils.RiverUtils; gernotbelger@8948: gernotbelger@8948: /** gernotbelger@8948: * Result type for data that goes into {@link SInfoResultRow}s. gernotbelger@8948: * gernotbelger@8948: * @author Gernot Belger gernotbelger@8948: */ gernotbelger@8948: public enum SInfoResultType { gernotbelger@8948: gernotbelger@8948: station(SInfoI18NStrings.UNIT_KM, SInfoI18NStrings.CSV_KM_HEADER) { gernotbelger@8948: @Override gernotbelger@8948: public String exportValue(final CallContext context, final Object value) { gernotbelger@8948: final double doubleValue = asDouble(value); gernotbelger@8948: return exportDoubleValue(context, doubleValue); gernotbelger@8948: } gernotbelger@8948: gernotbelger@8948: @Override gernotbelger@8948: protected NumberFormat createFormatter(final CallContext context) { gernotbelger@8948: return Formatter.getWaterlevelKM(context); gernotbelger@8948: } gernotbelger@8948: }, gernotbelger@8948: gernotbelger@8948: waterlevel(null, SInfoI18NStrings.CSV_WATERLEVEL_HEADER) { gernotbelger@8948: @Override gernotbelger@8948: public String exportValue(final CallContext context, final Object value) { gernotbelger@8948: final double doubleValue = asDouble(value); gernotbelger@8948: return exportDoubleValue(context, doubleValue); gernotbelger@8948: } gernotbelger@8948: gernotbelger@8948: @Override gernotbelger@8948: protected NumberFormat createFormatter(final CallContext context) { gernotbelger@8948: // REMARK: other modules use Formatter.getWaterlevelW(context) instead, but that format with a variable number of gernotbelger@8948: // digits. gernotbelger@8948: return Formatter.getFlowDepth(context); gernotbelger@8948: } gernotbelger@8948: }, gernotbelger@8948: gernotbelger@8948: waterlevelLabel(SInfoI18NStrings.UNIT_NONE, SInfoI18NStrings.CSV_LABEL_HEADER) { gernotbelger@8948: @Override gernotbelger@8948: public String exportValue(final CallContext context, final Object value) { gernotbelger@8948: return exportStringValue(value); gernotbelger@8948: } gernotbelger@8948: gernotbelger@8948: @Override gernotbelger@8948: protected NumberFormat createFormatter(final CallContext context) { gernotbelger@8948: throw new UnsupportedOperationException(); gernotbelger@8948: } gernotbelger@8948: }, gernotbelger@8948: gernotbelger@8948: discharge(SInfoI18NStrings.UNIT_CUBIC_M, SInfoI18NStrings.CSV_DISCHARGE_HEADER) { gernotbelger@8948: @Override gernotbelger@8948: public String exportValue(final CallContext context, final Object value) { gernotbelger@8948: final double doubleValue = asDouble(value); gernotbelger@8948: final double roundedDischarge = RiverUtils.roundQ(doubleValue); gernotbelger@8948: return exportDoubleValue(context, roundedDischarge); gernotbelger@8948: } gernotbelger@8948: gernotbelger@8948: @Override gernotbelger@8948: protected NumberFormat createFormatter(final CallContext context) { gernotbelger@8948: return Formatter.getWaterlevelQ(context); gernotbelger@8948: } gernotbelger@8948: }, gernotbelger@8948: gernotbelger@8949: // FIXME: use pgetPdfHeader instead of getCsvHeader gernotbelger@8949: gernotbelger@8949: meanBedHeight(null, SInfoI18NStrings.CSV_MEAN_BED_HEIGHT_HEADER, SInfoI18NStrings.CSV_MEAN_BED_HEIGHT_HEADER_SHORT) { gernotbelger@8948: @Override gernotbelger@8948: public String exportValue(final CallContext context, final Object value) { gernotbelger@8948: final double doubleValue = asDouble(value); gernotbelger@8948: return exportDoubleValue(context, doubleValue); gernotbelger@8948: } gernotbelger@8948: gernotbelger@8948: @Override gernotbelger@8948: protected NumberFormat createFormatter(final CallContext context) { gernotbelger@8948: return Formatter.getMeanBedHeight(context); gernotbelger@8948: } gernotbelger@8948: }, gernotbelger@8948: gernotbelger@8948: soundingLabel(SInfoI18NStrings.UNIT_NONE, SInfoI18NStrings.CSV_SOUNDING_HEADER) { gernotbelger@8948: @Override gernotbelger@8948: public String exportValue(final CallContext context, final Object value) { gernotbelger@8948: return exportStringValue(value); gernotbelger@8948: } gernotbelger@8948: gernotbelger@8948: @Override gernotbelger@8948: protected NumberFormat createFormatter(final CallContext context) { gernotbelger@8948: throw new UnsupportedOperationException(); gernotbelger@8948: } gernotbelger@8948: }, gernotbelger@8948: gernotbelger@8948: flowdepthmin(SInfoI18NStrings.UNIT_M, SInfoI18NStrings.CSV_FLOWDEPTH_MIN_HEADER) { gernotbelger@8948: @Override gernotbelger@8948: public String exportValue(final CallContext context, final Object value) { gernotbelger@8948: final double doubleValue = asDouble(value); gernotbelger@8948: return exportDoubleValue(context, doubleValue); gernotbelger@8948: } gernotbelger@8948: gernotbelger@8948: @Override gernotbelger@8948: protected NumberFormat createFormatter(final CallContext context) { gernotbelger@8948: return Formatter.getFlowDepth(context); gernotbelger@8948: } gernotbelger@8948: }, gernotbelger@8948: gernotbelger@8948: flowdepthmax(SInfoI18NStrings.UNIT_M, SInfoI18NStrings.CSV_FLOWDEPTH_MAX_HEADER) { gernotbelger@8948: @Override gernotbelger@8948: public String exportValue(final CallContext context, final Object value) { gernotbelger@8948: final double doubleValue = asDouble(value); gernotbelger@8948: return exportDoubleValue(context, doubleValue); gernotbelger@8948: } gernotbelger@8948: gernotbelger@8948: @Override gernotbelger@8948: protected NumberFormat createFormatter(final CallContext context) { gernotbelger@8948: return Formatter.getFlowDepth(context); gernotbelger@8948: } gernotbelger@8948: }, gernotbelger@8948: gernotbelger@8948: gaugeLabel(SInfoI18NStrings.UNIT_NONE, SInfoI18NStrings.CSV_GAUGE_HEADER) { gernotbelger@8948: @Override gernotbelger@8948: public String exportValue(final CallContext context, final Object value) { gernotbelger@8948: return exportStringValue(value); gernotbelger@8948: } gernotbelger@8948: gernotbelger@8948: @Override gernotbelger@8948: protected NumberFormat createFormatter(final CallContext context) { gernotbelger@8948: throw new UnsupportedOperationException(); gernotbelger@8948: } gernotbelger@8948: }, gernotbelger@8948: gernotbelger@8948: location(SInfoI18NStrings.UNIT_NONE, SInfoI18NStrings.CSV_LOCATION_HEADER) { gernotbelger@8948: @Override gernotbelger@8948: public String exportValue(final CallContext context, final Object value) { gernotbelger@8948: return exportStringValue(value); gernotbelger@8948: } gernotbelger@8948: gernotbelger@8948: @Override gernotbelger@8948: protected NumberFormat createFormatter(final CallContext context) { gernotbelger@8948: throw new UnsupportedOperationException(); gernotbelger@8948: } gernotbelger@8948: }, gernotbelger@8948: soilkind(SInfoI18NStrings.UNIT_NONE, SInfoI18NStrings.CSV_TKHKIND_HEADER) { gernotbelger@8948: @Override gernotbelger@8948: public String exportValue(final CallContext context, final Object value) { gernotbelger@8948: gernotbelger@8948: if (value == null) gernotbelger@8948: return StringUtils.EMPTY; gernotbelger@8948: gernotbelger@8948: final SoilKind kind = (SoilKind) value; gernotbelger@8948: gernotbelger@8948: final String key = SInfoI18NStrings.PREFIX_TKH_KIND + kind.name(); gernotbelger@8948: return Resources.getMsg(context.getMeta(), key, key); gernotbelger@8948: } gernotbelger@8948: gernotbelger@8948: @Override gernotbelger@8948: protected NumberFormat createFormatter(final CallContext context) { gernotbelger@8948: throw new UnsupportedOperationException(); gernotbelger@8948: } gernotbelger@8948: }, gernotbelger@8948: flowdepth(SInfoI18NStrings.UNIT_M, SInfoI18NStrings.CSV_FLOWDEPTH_HEADER) { gernotbelger@8948: @Override gernotbelger@8948: public String exportValue(final CallContext context, final Object value) { gernotbelger@8948: final double doubleValue = asDouble(value); gernotbelger@8948: return exportDoubleValue(context, doubleValue); gernotbelger@8948: } gernotbelger@8948: gernotbelger@8948: @Override gernotbelger@8948: protected NumberFormat createFormatter(final CallContext context) { gernotbelger@8948: return Formatter.getFlowDepth(context); gernotbelger@8948: } gernotbelger@8948: }, gernotbelger@8948: d50(null, null) { gernotbelger@8948: @Override gernotbelger@8948: public String exportValue(final CallContext context, final Object value) { gernotbelger@8948: final double doubleValue = asDouble(value); gernotbelger@8948: return exportDoubleValue(context, doubleValue); gernotbelger@8948: } gernotbelger@8948: gernotbelger@8948: @Override gernotbelger@8948: protected NumberFormat createFormatter(final CallContext context) { gernotbelger@8948: throw new UnsupportedOperationException(); gernotbelger@8948: } gernotbelger@8948: }, gernotbelger@8948: velocity(null, null) { gernotbelger@8948: @Override gernotbelger@8948: public String exportValue(final CallContext context, final Object value) { gernotbelger@8948: final double doubleValue = asDouble(value); gernotbelger@8948: return exportDoubleValue(context, doubleValue); gernotbelger@8948: } gernotbelger@8948: gernotbelger@8948: @Override gernotbelger@8948: protected NumberFormat createFormatter(final CallContext context) { gernotbelger@8948: throw new UnsupportedOperationException(); gernotbelger@8948: } gernotbelger@8948: }, gernotbelger@8948: tau(null, null) { gernotbelger@8948: @Override gernotbelger@8948: public String exportValue(final CallContext context, final Object value) { gernotbelger@8948: final double doubleValue = asDouble(value); gernotbelger@8948: return exportDoubleValue(context, doubleValue); gernotbelger@8948: } gernotbelger@8948: gernotbelger@8948: @Override gernotbelger@8948: protected NumberFormat createFormatter(final CallContext context) { gernotbelger@8948: throw new UnsupportedOperationException(); gernotbelger@8948: } gernotbelger@8948: }, gernotbelger@8949: tkh(SInfoI18NStrings.UNIT_CM, SInfoI18NStrings.CSV_TKH_HEADER, SInfoI18NStrings.CSV_TKH_HEADER_SHORT) { gernotbelger@8948: @Override gernotbelger@8948: public String exportValue(final CallContext context, final Object value) { gernotbelger@8948: final double doubleValue = asDouble(value); gernotbelger@8948: return exportDoubleValue(context, doubleValue); gernotbelger@8948: } gernotbelger@8948: gernotbelger@8948: @Override gernotbelger@8948: protected NumberFormat createFormatter(final CallContext context) { gernotbelger@8948: return Formatter.getTkh(context); gernotbelger@8948: } gernotbelger@8948: }, gernotbelger@8948: tkhup(SInfoI18NStrings.UNIT_CM, null) { gernotbelger@8948: @Override gernotbelger@8948: public String exportValue(final CallContext context, final Object value) { gernotbelger@8948: final double doubleValue = asDouble(value); gernotbelger@8948: return exportDoubleValue(context, doubleValue); gernotbelger@8948: } gernotbelger@8948: gernotbelger@8948: @Override gernotbelger@8948: protected NumberFormat createFormatter(final CallContext context) { gernotbelger@8948: throw new UnsupportedOperationException(); gernotbelger@8948: } gernotbelger@8948: }, gernotbelger@8948: tkhdown(SInfoI18NStrings.UNIT_CM, null) { gernotbelger@8948: @Override gernotbelger@8948: public String exportValue(final CallContext context, final Object value) { gernotbelger@8948: final double doubleValue = asDouble(value); gernotbelger@8948: return exportDoubleValue(context, doubleValue); gernotbelger@8948: } gernotbelger@8948: gernotbelger@8948: @Override gernotbelger@8948: protected NumberFormat createFormatter(final CallContext context) { gernotbelger@8948: throw new UnsupportedOperationException(); gernotbelger@8948: } gernotbelger@8948: }, gernotbelger@8948: flowdepthtkh(SInfoI18NStrings.UNIT_M, SInfoI18NStrings.CSV_FLOWDEPTHTKH_HEADER) { gernotbelger@8948: @Override gernotbelger@8948: public String exportValue(final CallContext context, final Object value) { gernotbelger@8948: final double doubleValue = asDouble(value); gernotbelger@8948: return exportDoubleValue(context, doubleValue); gernotbelger@8948: } gernotbelger@8948: gernotbelger@8948: @Override gernotbelger@8948: protected NumberFormat createFormatter(final CallContext context) { gernotbelger@8948: return Formatter.getFlowDepth(context); gernotbelger@8948: } gernotbelger@8948: }; gernotbelger@8948: gernotbelger@8948: /* Cache for formatters because Formatter will always create new formats (which is very expensive) */ gernotbelger@8948: private final Map formatters = new HashMap<>(); gernotbelger@8948: gernotbelger@8948: private final String unit; gernotbelger@8948: gernotbelger@8948: private final String csvHeader; gernotbelger@8948: gernotbelger@8949: private final String pdfHeader; gernotbelger@8949: gernotbelger@8949: private SInfoResultType(final String unit, final String csvAndPdfHeader) { gernotbelger@8949: this(unit, csvAndPdfHeader, csvAndPdfHeader); gernotbelger@8949: } gernotbelger@8949: gernotbelger@8949: private SInfoResultType(final String unit, final String csvHeader, final String pdfHeader) { gernotbelger@8949: this.unit = unit; gernotbelger@8948: this.csvHeader = csvHeader; gernotbelger@8949: this.pdfHeader = pdfHeader; gernotbelger@8948: } gernotbelger@8948: gernotbelger@8948: public abstract String exportValue(final CallContext context, final Object value); gernotbelger@8948: gernotbelger@8948: protected final String exportStringValue(final Object value) { gernotbelger@8948: gernotbelger@8948: if (value == null) gernotbelger@8948: return StringUtils.EMPTY; gernotbelger@8948: gernotbelger@8948: if (!(value instanceof String)) gernotbelger@8948: throw new IllegalStateException(); gernotbelger@8948: gernotbelger@8948: return (String) value; gernotbelger@8948: } gernotbelger@8948: gernotbelger@8948: protected final double asDouble(final Object value) { gernotbelger@8948: if (value == null) gernotbelger@8948: return Double.NaN; gernotbelger@8948: gernotbelger@8948: if (!(value instanceof Number)) gernotbelger@8948: throw new IllegalStateException(); gernotbelger@8948: gernotbelger@8948: final Number number = (Number) value; gernotbelger@8948: return number.doubleValue(); gernotbelger@8948: } gernotbelger@8948: gernotbelger@8948: protected final String exportDoubleValue(final CallContext context, final double value) { gernotbelger@8948: if (Double.isNaN(value)) gernotbelger@8948: return StringUtils.EMPTY; gernotbelger@8948: gernotbelger@8948: final NumberFormat formatter = getFormatter(context); gernotbelger@8948: return formatter.format(value); gernotbelger@8948: } gernotbelger@8948: gernotbelger@8948: private NumberFormat getFormatter(final CallContext context) { gernotbelger@8948: final CallMeta meta = context.getMeta(); gernotbelger@8948: final Locale locale = Resources.getLocale(meta); gernotbelger@8948: gernotbelger@8948: if (!this.formatters.containsKey(locale)) gernotbelger@8948: this.formatters.put(locale, createFormatter(context)); gernotbelger@8948: gernotbelger@8948: return this.formatters.get(locale); gernotbelger@8948: } gernotbelger@8948: gernotbelger@8948: protected abstract NumberFormat createFormatter(CallContext context); gernotbelger@8948: gernotbelger@8948: public final String getCsvHeader() { gernotbelger@8948: return this.csvHeader; gernotbelger@8948: } gernotbelger@8948: gernotbelger@8949: public String getPdfHeader(final CallMeta meta) { gernotbelger@8949: return Resources.getMsg(meta, this.pdfHeader, this.pdfHeader); gernotbelger@8949: } gernotbelger@8949: gernotbelger@8948: public final String getUnit() { gernotbelger@8948: return this.unit; gernotbelger@8948: } gernotbelger@8948: }