gernotbelger@8933: /** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde gernotbelger@8933: * Software engineering by gernotbelger@8933: * Björnsen Beratende Ingenieure GmbH gernotbelger@8933: * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt gernotbelger@8933: * gernotbelger@8933: * This file is Free Software under the GNU AGPL (>=v3) gernotbelger@8933: * and comes with ABSOLUTELY NO WARRANTY! Check out the gernotbelger@8933: * documentation coming with Dive4Elements River for details. gernotbelger@8933: */ gernotbelger@8933: package org.dive4elements.river.exports; gernotbelger@8933: gernotbelger@8933: import java.text.NumberFormat; gernotbelger@8933: gernotbelger@8933: import org.dive4elements.artifacts.CallContext; gernotbelger@8933: import org.dive4elements.river.artifacts.D4EArtifact; gernotbelger@8933: import org.dive4elements.river.artifacts.WINFOArtifact; gernotbelger@8933: import org.dive4elements.river.artifacts.model.WQKms; gernotbelger@8933: import org.dive4elements.river.artifacts.resources.Resources; gernotbelger@8933: import org.dive4elements.river.utils.Formatter; gernotbelger@8933: import org.dive4elements.river.utils.RiverUtils; gernotbelger@8933: import org.dive4elements.river.utils.RiverUtils.WQ_MODE; gernotbelger@8933: gernotbelger@8933: /** gernotbelger@8933: * Helper that encapsulates the logic how the 'description' column in waterlevel exporting is generated. gernotbelger@8933: * TODO: this class should also be used in WaterlevelExport (all code is copied from there), but this would involve gernotbelger@8933: * heavy testing and we leave this to the one who is responsible to clean up this mess. gernotbelger@8933: * gernotbelger@8933: * @author Gernot Belger gernotbelger@8933: */ gernotbelger@8933: public final class WaterlevelDescriptionBuilder { gernotbelger@8933: gernotbelger@8933: private static final String CSV_Q_DESC_HEADER = "export.waterlevel.csv.header.q.desc"; gernotbelger@8933: gernotbelger@8933: // FIXME: missing in resource-files! hence always the default is used... gernotbelger@8933: private static final String CSV_W_DESC_HEADER = "export.waterlevel.csv.header.w.desc"; gernotbelger@8933: gernotbelger@8933: private static final String DEFAULT_CSV_Q_DESC_HEADER = "Bezeichnung"; gernotbelger@8933: gernotbelger@8933: private static final String DEFAULT_CSV_W_DESC_HEADER = "W/Pegel [cm]"; gernotbelger@8933: gernotbelger@8933: private final boolean isQ; gernotbelger@8933: gernotbelger@8933: private final boolean atGauge; gernotbelger@8933: gernotbelger@8933: private final CallContext context; gernotbelger@8933: gernotbelger@8933: private final WQ_MODE mode; gernotbelger@8933: gernotbelger@8933: private final D4EArtifact artifact; gernotbelger@8933: gernotbelger@8933: public WaterlevelDescriptionBuilder(final D4EArtifact artifact, final CallContext context) { gernotbelger@8933: this.context = context; gernotbelger@8933: gernotbelger@8933: // REMARK: taken from WaterlevelExporter, should be moved into WInfoArtifact gernotbelger@8933: this.mode = RiverUtils.getWQMode(artifact); gernotbelger@8933: this.atGauge = this.mode == WQ_MODE.QGAUGE || this.mode == WQ_MODE.WGAUGE; gernotbelger@8933: this.isQ = this.mode == WQ_MODE.QGAUGE || this.mode == WQ_MODE.QFREE; gernotbelger@8933: gernotbelger@8933: this.artifact = artifact; gernotbelger@8933: } gernotbelger@8933: gernotbelger@8933: public boolean isAtGauge() { gernotbelger@8933: return this.atGauge; gernotbelger@8933: } gernotbelger@8933: gernotbelger@8933: public String getColumnHeader() { gernotbelger@8933: gernotbelger@8933: if (!this.atGauge) gernotbelger@8933: return null; gernotbelger@8933: gernotbelger@8933: // REMARK: bad inter-dependency to WaterlevelExporter, but we want to really copy the logic from WInfo gernotbelger@8933: if (this.isQ) gernotbelger@8933: return Resources.getMsg(this.context.getMeta(), CSV_Q_DESC_HEADER, DEFAULT_CSV_Q_DESC_HEADER); gernotbelger@8933: gernotbelger@8933: return Resources.getMsg(this.context.getMeta(), CSV_W_DESC_HEADER, DEFAULT_CSV_W_DESC_HEADER); gernotbelger@8933: } gernotbelger@8933: gernotbelger@8933: public String getDesc(final WQKms wqkms) { gernotbelger@8933: return getDesc(wqkms, this.isQ); gernotbelger@8933: } gernotbelger@8933: gernotbelger@8933: public String getDesc(final WQKms wqkms, final boolean isQoverride) { gernotbelger@8933: String colDesc = ""; gernotbelger@8933: gernotbelger@8933: if (this.artifact instanceof WINFOArtifact && isQoverride) { gernotbelger@8933: colDesc = getCSVRowTitle((WINFOArtifact) this.artifact, wqkms); gernotbelger@8933: } else if (!isQoverride) { gernotbelger@8933: final Double value = RiverUtils.getValueFromWQ(wqkms); gernotbelger@8933: colDesc = (value != null) ? Formatter.getWaterlevelW(this.context).format(value) : null; gernotbelger@8933: } gernotbelger@8933: gernotbelger@8933: if (this.artifact instanceof WINFOArtifact) { gernotbelger@8933: if (wqkms != null && wqkms.getRawValue() != null) { gernotbelger@8933: final WINFOArtifact winfo = (WINFOArtifact) this.artifact; gernotbelger@8933: colDesc = RiverUtils.getNamedMainValue(winfo, wqkms.getRawValue()); gernotbelger@8933: // For 'W am Pegel' s gernotbelger@8933: if (colDesc == null) { gernotbelger@8933: final Double value = RiverUtils.getValueFromWQ(wqkms); gernotbelger@8933: colDesc = (value != null) ? Formatter.getWaterlevelW(this.context).format(value) : null; gernotbelger@8933: } gernotbelger@8933: } gernotbelger@8933: } gernotbelger@8933: gernotbelger@8933: if (colDesc == null) gernotbelger@8933: return ""; gernotbelger@8933: gernotbelger@8933: /* gernotbelger@8933: * Quick hack. Can be removed when database strings are gernotbelger@8933: * adapted or left in here as it should never be harmful. gernotbelger@8933: */ gernotbelger@8933: return colDesc.replace("Amtl.Festlegung_", "Amtl. "); gernotbelger@8933: } gernotbelger@8933: gernotbelger@8933: private String getCSVRowTitle(final WINFOArtifact winfo, final WQKms wqkms) { gernotbelger@8933: gernotbelger@8933: if (this.mode == WQ_MODE.WFREE || this.mode == WQ_MODE.QGAUGE) gernotbelger@8933: return localizeWQKms(wqkms); gernotbelger@8933: gernotbelger@8933: final Double v = wqkms.getRawValue(); gernotbelger@8933: gernotbelger@8933: final String nmv = RiverUtils.getNamedMainValue(winfo, v); gernotbelger@8933: gernotbelger@8933: if (nmv != null && nmv.length() > 0) { gernotbelger@8933: return RiverUtils.stripNamedMainValue(nmv); gernotbelger@8933: } gernotbelger@8933: gernotbelger@8933: return localizeWQKms(wqkms); gernotbelger@8933: } gernotbelger@8933: gernotbelger@8933: /** gernotbelger@8933: * Get a string like 'W=' or 'Q=' with a number following in localized gernotbelger@8933: * format. gernotbelger@8933: */ gernotbelger@8933: private String localizeWQKms(final WQKms wqkms) { gernotbelger@8933: final Double rawValue = wqkms.getRawValue(); gernotbelger@8933: gernotbelger@8933: if (rawValue == null) { gernotbelger@8933: return wqkms.getName(); gernotbelger@8933: } gernotbelger@8933: gernotbelger@8933: final NumberFormat nf = Formatter.getRawFormatter(this.context); gernotbelger@8933: gernotbelger@8933: if (this.mode == WQ_MODE.WFREE || this.mode == WQ_MODE.WGAUGE) gernotbelger@8933: return "W=" + nf.format(rawValue); gernotbelger@8933: gernotbelger@8933: return "Q=" + nf.format(rawValue); gernotbelger@8933: } gernotbelger@8933: }