# HG changeset patch
# User gernotbelger
# Date 1516357422 -3600
# Node ID 28df64078f279b595aed33f133e4336465fab5e2
# Parent 7bbfb24e6eec67d3163b802cb094ae93ae41ba43# Parent 0862ea5d66baf60e7eee496d130a35157cc9ec12
Merge with 0862ea5d66baf60e7eee496d130a35157cc9ec12
diff -r 0862ea5d66ba -r 28df64078f27 artifacts/TODO
--- a/artifacts/TODO Thu Jan 18 20:54:03 2018 +0100
+++ b/artifacts/TODO Fri Jan 19 11:23:42 2018 +0100
@@ -1,1 +1,1 @@
-- Validation of the input values of an incoming feed() call
+- Validation of the input values of an incoming feed() call
\ No newline at end of file
diff -r 0862ea5d66ba -r 28df64078f27 artifacts/doc/conf/artifacts/manualpoints.xml
--- a/artifacts/doc/conf/artifacts/manualpoints.xml Thu Jan 18 20:54:03 2018 +0100
+++ b/artifacts/doc/conf/artifacts/manualpoints.xml Fri Jan 19 11:23:42 2018 +0100
@@ -35,6 +35,8 @@
+
+
diff -r 0862ea5d66ba -r 28df64078f27 artifacts/doc/conf/artifacts/sinfo.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/doc/conf/artifacts/sinfo.xml Fri Jan 19 11:23:42 2018 +0100
@@ -0,0 +1,101 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 0862ea5d66ba -r 28df64078f27 artifacts/doc/conf/backend-db.xml
--- a/artifacts/doc/conf/backend-db.xml Thu Jan 18 20:54:03 2018 +0100
+++ b/artifacts/doc/conf/backend-db.xml Fri Jan 19 11:23:42 2018 +0100
@@ -5,7 +5,7 @@
d4e
org.hibernate.dialect.PostgreSQLDialect
org.postgresql.Driver
- jdbc:postgresql://localhost:5432/d4e
+ jdbc:postgresql://localhost:63333/d4e
select 1 from rivers
30000
diff -r 0862ea5d66ba -r 28df64078f27 artifacts/doc/conf/conf.xml
--- a/artifacts/doc/conf/conf.xml Thu Jan 18 20:54:03 2018 +0100
+++ b/artifacts/doc/conf/conf.xml Fri Jan 19 11:23:42 2018 +0100
@@ -22,6 +22,8 @@
+
+
]>
YOUR_SECRET
@@ -168,6 +170,12 @@
org.dive4elements.artifactdatabase.DefaultArtifactFactory
+
+
+ org.dive4elements.artifactdatabase.DefaultArtifactFactory
+
org.dive4elements.artifactdatabase.DefaultUserFactory
@@ -299,6 +307,8 @@
&gaugedischargecurve-artifact;
&sedimentload-artifact;
&sedimentload-ls-artifact;
+
+ &sinfo_artifact;
&modules;
diff -r 0862ea5d66ba -r 28df64078f27 artifacts/doc/conf/generators/generators.xml
--- a/artifacts/doc/conf/generators/generators.xml Thu Jan 18 20:54:03 2018 +0100
+++ b/artifacts/doc/conf/generators/generators.xml Fri Jan 19 11:23:42 2018 +0100
@@ -58,5 +58,10 @@
+
+
+
+
+
diff -r 0862ea5d66ba -r 28df64078f27 artifacts/doc/conf/generators/longitudinal-diagram-defaults.xml
--- a/artifacts/doc/conf/generators/longitudinal-diagram-defaults.xml Thu Jan 18 20:54:03 2018 +0100
+++ b/artifacts/doc/conf/generators/longitudinal-diagram-defaults.xml Fri Jan 19 11:23:42 2018 +0100
@@ -14,8 +14,8 @@
-
+
+
@@ -42,4 +42,7 @@
-
+
+
+
+
\ No newline at end of file
diff -r 0862ea5d66ba -r 28df64078f27 artifacts/doc/conf/generators/longitudinal-diagrams.xml
--- a/artifacts/doc/conf/generators/longitudinal-diagrams.xml Thu Jan 18 20:54:03 2018 +0100
+++ b/artifacts/doc/conf/generators/longitudinal-diagrams.xml Fri Jan 19 11:23:42 2018 +0100
@@ -87,5 +87,20 @@
-
+
+
+
+ &longitudinal-defaults;
+
+
+
+
+
+
\ No newline at end of file
diff -r 0862ea5d66ba -r 28df64078f27 artifacts/doc/conf/jasper/FIXME.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/doc/conf/jasper/FIXME.txt Fri Jan 19 11:23:42 2018 +0100
@@ -0,0 +1,6 @@
+Awful:
+- source files together with compiled files in one directory
+- source files part of 'conf', but user will probably never be able to conf them
+- compiled files checked-in into SCM
+- compilation process not part of maven (not even part of project at all)
+- we have different jasper reports for different languages; instead introduce variables and give i10n strings as report variables
\ No newline at end of file
diff -r 0862ea5d66ba -r 28df64078f27 artifacts/doc/conf/jasper/templates/sinfo.flowdepth.jrxml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/doc/conf/jasper/templates/sinfo.flowdepth.jrxml Fri Jan 19 11:23:42 2018 +0100
@@ -0,0 +1,215 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r 0862ea5d66ba -r 28df64078f27 artifacts/doc/conf/log4j.properties
--- a/artifacts/doc/conf/log4j.properties Thu Jan 18 20:54:03 2018 +0100
+++ b/artifacts/doc/conf/log4j.properties Fri Jan 19 11:23:42 2018 +0100
@@ -4,7 +4,7 @@
log4j.category.org.hibernate=WARN
log4j.category.net.sf.ehcache=WARN
log4j.category.org.eclipse=WARN
-log4j.category.org.restlet=INFO
+log4j.category.org.restlet=WARN
########## APPENDER SETTINGS
@@ -12,10 +12,7 @@
log4j.appender.FLYS.layout.ConversionPattern=%d{HH:mm:ss} [%t] %-5p %c{1} - %m%n
-log4j.appender.FLYS=org.apache.log4j.RollingFileAppender
-log4j.appender.FLYS.File=/var/log/d4e-river/d4e-server.log
-log4j.appender.FLYS.MaxFileSize=5000KB
-log4j.appender.FLYS.MaxBackupIndex=1
+log4j.appender.FLYS=org.apache.log4j.ConsoleAppender
log4j.logger.org.dive4elements.artifactdatabase.rest.Standalone=INFO, START
log4j.appender.START=org.apache.log4j.ConsoleAppender
diff -r 0862ea5d66ba -r 28df64078f27 artifacts/doc/conf/meta-data.xml
--- a/artifacts/doc/conf/meta-data.xml Thu Jan 18 20:54:03 2018 +0100
+++ b/artifacts/doc/conf/meta-data.xml Fri Jan 19 11:23:42 2018 +0100
@@ -242,6 +242,19 @@
+
+ S-INFO
+
+
+
+
+
+
+
+
+
+
+
diff -r 0862ea5d66ba -r 28df64078f27 artifacts/doc/conf/modules.xml
--- a/artifacts/doc/conf/modules.xml Thu Jan 18 20:54:03 2018 +0100
+++ b/artifacts/doc/conf/modules.xml Fri Jan 19 11:23:42 2018 +0100
@@ -3,6 +3,9 @@
+
+
+
@@ -15,5 +18,4 @@
-
-
+
\ No newline at end of file
diff -r 0862ea5d66ba -r 28df64078f27 artifacts/doc/conf/seddb-db.xml
--- a/artifacts/doc/conf/seddb-db.xml Thu Jan 18 20:54:03 2018 +0100
+++ b/artifacts/doc/conf/seddb-db.xml Fri Jan 19 11:23:42 2018 +0100
@@ -5,7 +5,7 @@
seddb
org.hibernate.dialect.PostgreSQLDialect
org.postgresql.Driver
- jdbc:postgresql://localhost:5432/seddb
+ jdbc:postgresql://localhost:63333/seddb
select 1 from gewaesser
30000
+
+
+
-
-
+
\ No newline at end of file
diff -r 0862ea5d66ba -r 28df64078f27 artifacts/doc/conf/themes/default.xml
--- a/artifacts/doc/conf/themes/default.xml Thu Jan 18 20:54:03 2018 +0100
+++ b/artifacts/doc/conf/themes/default.xml Fri Jan 19 11:23:42 2018 +0100
@@ -2872,4 +2872,16 @@
+
+
+
+
+
+
+
+
+
+
+
diff -r 0862ea5d66ba -r 28df64078f27 artifacts/doc/conf/themes/second.xml
--- a/artifacts/doc/conf/themes/second.xml Thu Jan 18 20:54:03 2018 +0100
+++ b/artifacts/doc/conf/themes/second.xml Fri Jan 19 11:23:42 2018 +0100
@@ -2869,4 +2869,15 @@
-
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 0862ea5d66ba -r 28df64078f27 artifacts/src/main/java/org/dive4elements/river/artifacts/model/DataFacet.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/model/DataFacet.java Thu Jan 18 20:54:03 2018 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/model/DataFacet.java Fri Jan 19 11:23:42 2018 +0100
@@ -104,12 +104,14 @@
*/
@Override
public Facet deepCopy() {
+ // FIXME: why not use the full constructor instead? would also fix the next problem
DataFacet copy = new DataFacet();
+ // FIXME: usage of internal knowledge of parent class...
+ // Either the set method should be correctly overwritten, or implement a correct copy-constructor!
copy.set(this);
copy.type = type;
copy.hash = hash;
copy.stateId = stateId;
return copy;
}
-}
-// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :
+}
\ No newline at end of file
diff -r 0862ea5d66ba -r 28df64078f27 artifacts/src/main/java/org/dive4elements/river/artifacts/model/FacetTypes.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/model/FacetTypes.java Thu Jan 18 20:54:03 2018 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/model/FacetTypes.java Fri Jan 19 11:23:42 2018 +0100
@@ -189,6 +189,8 @@
SQF("sq_relation_f"),
HD("historical_discharge"),
HDWQ("historical_discharge_wq");
+ // FIXME: do we need this? and why?
+ // SFD("sinfo_flow_depth");
private String chartTypeString;
diff -r 0862ea5d66ba -r 28df64078f27 artifacts/src/main/java/org/dive4elements/river/artifacts/resources/Resources.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/resources/Resources.java Thu Jan 18 20:54:03 2018 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/resources/Resources.java Fri Jan 19 11:23:42 2018 +0100
@@ -124,18 +124,18 @@
* @return a translated string.
*/
public static String getMsg(
- CallMeta meta,
- String key,
- String def,
- Object[] args)
+ CallMeta meta,
+ String key,
+ String def,
+ Object... args)
{
- String template = getMsg(meta, key, (String)null);
-
- if (template == null) {
- return def;
- }
-
- return format(meta, template, args);
+ String template = getMsg(meta, key, (String)null);
+
+ if (template == null) {
+ return def;
+ }
+
+ return format(meta, template, args);
}
public static String format(
diff -r 0862ea5d66ba -r 28df64078f27 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/CalculationSelectSinfo.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/CalculationSelectSinfo.java Fri Jan 19 11:23:42 2018 +0100
@@ -0,0 +1,78 @@
+/* Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
+ * Software engineering by
+ * Björnsen Beratende Ingenieure GmbH
+ * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+
+package org.dive4elements.river.artifacts.sinfo;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.apache.log4j.Logger;
+import org.dive4elements.artifacts.Artifact;
+import org.dive4elements.artifacts.CallContext;
+import org.dive4elements.artifacts.CallMeta;
+import org.dive4elements.artifacts.common.utils.XMLUtils;
+import org.dive4elements.river.artifacts.resources.Resources;
+import org.dive4elements.river.artifacts.states.DefaultState;
+import org.w3c.dom.Element;
+
+/**
+ * @author Gernot Belger
+ */
+public class CalculationSelectSinfo extends DefaultState {
+
+ private static final long serialVersionUID = 1L;
+
+ /** The log that is used in this class. */
+ private static Logger log = Logger.getLogger(CalculationSelectSinfo.class);
+
+ public CalculationSelectSinfo() {
+ }
+
+
+ @Override
+ protected Element[] createItems(
+ XMLUtils.ElementCreator cr,
+ Artifact artifact,
+ String name,
+ CallContext context)
+ {
+ final CallMeta meta = context.getMeta();
+
+ final Collection calcs = new ArrayList<>(SinfoCalcMode.values().length);
+
+ for (final SinfoCalcMode calcMode : SinfoCalcMode.values()) {
+ final String calc = calcMode.name();
+
+ final String label = Resources.getMsg(meta, calc, calc);
+
+ final Element element = createItem(
+ cr, new String[] {
+ label,
+ calc
+ });
+ calcs.add(element);
+ }
+
+ return calcs.toArray(new Element[calcs.size()]);
+ }
+
+ @Override
+ public boolean validate(Artifact artifact)
+ throws IllegalArgumentException
+ {
+ log.debug("CalculationSelect.validate");
+
+ final SINFOArtifact sinfo = (SINFOArtifact) artifact;
+ /* throws an exception if calculation mode is invalid */
+ sinfo.getCalculationMode();
+ return true;
+ }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :
diff -r 0862ea5d66ba -r 28df64078f27 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/SINFOArtifact.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/SINFOArtifact.java Fri Jan 19 11:23:42 2018 +0100
@@ -0,0 +1,73 @@
+/* Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
+ * Software engineering by
+ * Björnsen Beratende Ingenieure GmbH
+ * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+package org.dive4elements.river.artifacts.sinfo;
+
+import org.apache.commons.lang.StringUtils;
+import org.dive4elements.river.artifacts.D4EArtifact;
+
+/**
+ * The default MINFO artifact.
+ *
+ * @author Gernot Belger
+ */
+public class SINFOArtifact
+extends D4EArtifact
+{
+ /** Error message that is thrown if no mode has been chosen. */
+ private static final String ERROR_NO_CALCULATION_MODE =
+ "error_feed_no_calculation_mode";
+
+ /** Error message that is thrown if an invalid calculation mode has been
+ * chosen. */
+ private static final String ERROR_INVALID_CALCULATION_MODE =
+ "error_feed_invalid_calculation_mode";
+
+
+ /** The name of the artifact. */
+ private static final String ARTIFACT_NAME = "sinfo";
+
+ private static final String FIELD_FIVER = "river";
+
+ private static final String FIELD_MODE = "calculation_mode";
+
+ /**
+ * Default constructor, because it's serializable.
+ */
+ public SINFOArtifact() {
+ }
+
+ /**
+ * Returns the name of the concrete artifact.
+ *
+ * @return the name of the concrete artifact.
+ */
+ @Override
+ public String getName() {
+ return ARTIFACT_NAME;
+ }
+
+ public SinfoCalcMode getCalculationMode() {
+
+ final String calc = getDataAsString(FIELD_MODE);
+ if (calc == null) {
+ throw new IllegalArgumentException(ERROR_NO_CALCULATION_MODE);
+ }
+
+ try {
+ return SinfoCalcMode.valueOf(StringUtils.trimToEmpty(calc).toLowerCase());
+ } catch (Exception e) {
+ throw new IllegalArgumentException(ERROR_INVALID_CALCULATION_MODE, e);
+ }
+ }
+
+ public String getRiver() {
+ return getDataAsString(FIELD_FIVER);
+ }
+}
\ No newline at end of file
diff -r 0862ea5d66ba -r 28df64078f27 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/SinfoCalcMode.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/SinfoCalcMode.java Fri Jan 19 11:23:42 2018 +0100
@@ -0,0 +1,20 @@
+/* Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
+ * Software engineering by
+ * Björnsen Beratende Ingenieure GmbH
+ * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+
+package org.dive4elements.river.artifacts.sinfo;
+
+public enum SinfoCalcMode{
+ sinfo_calc_flow_depth,
+ sinfo_calc_flow_depth_development,
+ sinfo_calc_flow_depth_minmax,
+ sinfo_calc_grounding,
+ sinfo_calc_transport_bodies_heights,
+ sinfo_calc_infrastructures_inundation_duration
+}
\ No newline at end of file
diff -r 0862ea5d66ba -r 28df64078f27 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthAccess.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthAccess.java Fri Jan 19 11:23:42 2018 +0100
@@ -0,0 +1,88 @@
+/* Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
+ * Software engineering by
+ * Björnsen Beratende Ingenieure GmbH
+ * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+
+package org.dive4elements.river.artifacts.sinfo.flowdepth;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+
+import org.dive4elements.river.artifacts.access.RangeAccess;
+import org.dive4elements.river.artifacts.sinfo.SINFOArtifact;
+import org.dive4elements.river.artifacts.sinfo.SinfoCalcMode;
+import org.dive4elements.river.backend.utils.StringUtil;
+
+/**
+ * Access to the flow depth calculation type specific SInfo artifact data.
+ * REMARK: this class is NOT intended to be hold in the results (or anywhere else), in order to avoid a permanent reference to the artifact instance.
+ * Hence we do NOT cache any data.
+ *
+ * @author Gernot Belger
+ */
+public class FlowDepthAccess
+extends RangeAccess
+{
+ public static class DifferencesPair
+ {
+ private final String wstId;
+ private final String soundingId;
+
+ public DifferencesPair( final String wstId, final String soundingId ) {
+ this.wstId = wstId;
+ this.soundingId = soundingId;
+ }
+
+ public String getWstId() {
+ return this.wstId;
+ }
+
+ public String getSoundingId() {
+ return this.soundingId;
+ }
+ }
+
+ private static final String FIELD_USE_TKH = "use_transport_bodies"; //$NON-NLS-1$
+
+ public FlowDepthAccess(final SINFOArtifact artifact) {
+ super(artifact);
+
+ /* assert calculation mode */
+ final SinfoCalcMode calculationMode = artifact.getCalculationMode();
+ assert(calculationMode == SinfoCalcMode.sinfo_calc_flow_depth);
+ }
+
+ public boolean isUseTransportBodies() {
+ final Boolean useTkh = artifact.getDataAsBoolean( FIELD_USE_TKH );
+ return useTkh == null ? false : useTkh;
+ }
+
+ public Collection getDifferencePairs() {
+
+ final Collection diffPairs = new ArrayList<>();
+
+ final String diffids = super.getString("diffids");
+ if( diffids == null )
+ {
+ // Should never happen as this is handled by the ui
+ return Collections.emptyList();
+ }
+
+ // FIXME: this way of parsing the datacage-ids is repeated all over flys!
+ final String datas[] = diffids.split("#");
+ for(int i = 0; i < datas.length; i+=2) {
+ final String leftId = StringUtil.unbracket( datas[i] );
+ final String rightId = StringUtil.unbracket( datas[i+1] );
+
+ diffPairs.add(new DifferencesPair(leftId, rightId));
+ }
+
+ return Collections.unmodifiableCollection(diffPairs);
+ }
+}
\ No newline at end of file
diff -r 0862ea5d66ba -r 28df64078f27 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculation.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculation.java Fri Jan 19 11:23:42 2018 +0100
@@ -0,0 +1,152 @@
+/* Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
+ * Software engineering by
+ * Björnsen Beratende Ingenieure GmbH
+ * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+package org.dive4elements.river.artifacts.sinfo.flowdepth;
+
+import java.util.Collection;
+import java.util.List;
+
+import org.dive4elements.artifacts.CallContext;
+import org.dive4elements.river.artifacts.BedHeightsArtifact;
+import org.dive4elements.river.artifacts.model.Calculation;
+import org.dive4elements.river.artifacts.model.CalculationResult;
+import org.dive4elements.river.artifacts.model.LocationProvider;
+import org.dive4elements.river.artifacts.model.WKms;
+import org.dive4elements.river.artifacts.resources.Resources;
+import org.dive4elements.river.artifacts.sinfo.SINFOArtifact;
+import org.dive4elements.river.artifacts.sinfo.flowdepth.FlowDepthAccess.DifferencesPair;
+import org.dive4elements.river.artifacts.states.WDifferencesState;
+import org.dive4elements.river.model.BedHeight;
+import org.dive4elements.river.model.Gauge;
+import org.dive4elements.river.model.River;
+import org.dive4elements.river.utils.GaugeIndex;
+import org.dive4elements.river.utils.RiverUtils;
+
+class FlowDepthCalculation {
+
+ private static final String CSV_NOT_IN_GAUGE_RANGE = "export.waterlevel.csv.not.in.gauge.range";
+
+ private CallContext context;
+
+ public FlowDepthCalculation( final CallContext context ) {
+ this.context = context;
+ }
+
+ public CalculationResult calculate(final SINFOArtifact sinfo) {
+
+ /* access input data */
+ final FlowDepthAccess access = new FlowDepthAccess(sinfo);
+ final River river = access.getRiver();
+
+ final Collection diffPairs = access.getDifferencePairs();
+
+ final double from = access.getFrom();
+ final double to = access.getTo();
+
+ final boolean useTkh = access.isUseTransportBodies();
+
+ /* calculate results for each diff pair */
+ final Calculation problems = new Calculation();
+
+ final List gauges = river.determineGauges(from, to);
+ final GaugeIndex gaugeIndex = new GaugeIndex(gauges);
+
+ final FlowDepthCalculationResults results = new FlowDepthCalculationResults(river, from, to, useTkh);
+
+ for (final DifferencesPair diffPair : diffPairs) {
+ final FlowDepthCalculationResult result = calculateResult( river, from, to, diffPair, problems, gaugeIndex );
+ if( result != null )
+ results.addResult(result);
+ }
+
+ return new CalculationResult(results,problems);
+ }
+
+ private FlowDepthCalculationResult calculateResult(final River river, final double from, final double to, final DifferencesPair diffPair, final Calculation problems, final GaugeIndex gaugeIndex) {
+
+ /* access real input data from database */
+ final String soundingId = diffPair.getSoundingId();
+ final String wstId = diffPair.getWstId();
+
+ final BedHeight bedHeight = loadBedHeight( soundingId, from, to );
+ final WKms wstKms = new WDifferencesState().getWKms(wstId, context, from, to);
+ if( bedHeight == null || wstKms == null )
+ return null;
+
+ final FlowDepthCalculationResult resultData = new FlowDepthCalculationResult(wstKms.getName(), bedHeight.getDescription());
+
+ final String notinrange = Resources.getMsg(context.getMeta(), CSV_NOT_IN_GAUGE_RANGE, CSV_NOT_IN_GAUGE_RANGE);
+
+ // TODO: unklarheiten
+ // 'idealerweise alle 100m' was heisst das? kann doch nur durch datenverfügbarkeit bestimmt werden
+ // wie mit unterschiedlichen Ranges umgehen? Schnitt bilden? Fehlermeldung? ...?
+ // wie interpolieren? wst interpolieren? peilung interpolieren?
+
+ // FIXME: für die Berechnung der TKH sind weitere 'in FLYS vorliegende' Daten notwendig.
+ // aktuell unklar ob das durch andere Barten berechnete Werte oder Basisdaten sind
+ // TODO: check Vergleiche BArt 'Transportkörperhöhen'
+
+ // TODO: Berechnung der Transportkörperhöhen
+ // - woher kommen die zusätzlichen eingangsdaten? sind das fixe daten pro gewässer? --> falls ja, warum nicht einmal berechnen und in db ablegen?
+
+ final String bedHeightLabel = bedHeight.getDescription();
+ final String wstLabel = wstKms.getName();
+
+ for (int i = 0; i < wstKms.size(); i++) {
+
+ final double km = wstKms.getKm(i);
+ final double wst = wstKms.getW(i);
+ // FIXME: interpolate from bedheights?
+ final double meanBedHeight = 79.32;
+
+ final double flowDepth = wst - meanBedHeight;
+
+ final double tkh = 0;
+ final double flowDepthTkh = flowDepth - tkh;
+
+ // FIXME: discharge not available for all wst? or any?
+ final double discharge = 0.0;
+
+ // REMARK: access the location once only during calculation
+ final String location = LocationProvider.getLocation(river.getName(), km);
+
+ // REMARK: access the gauge once only during calculation
+ final Gauge gauge = gaugeIndex.findGauge(km);
+ final String gaugeLabel = gauge == null ? notinrange : gauge.getName();
+
+ resultData.addRow( km, flowDepth, flowDepthTkh, tkh, wst, discharge, wstLabel, gaugeLabel, meanBedHeight, bedHeightLabel, location );
+ }
+
+ return resultData;
+ }
+
+ private BedHeight loadBedHeight(final String soundingId, final double from, final double to) {
+
+ // FIXME: absolutely unbelievable....
+ // The way how bed-heights (and other data too) is accessed is different for nearly ever calculation-type throughout flys.
+ // The knowledge on how to parse the datacage-ids is spread thorugh the complete code-base...
+
+ // We use here the way on how bed-heights are accessed by the BedDifferenceAccess/BedDifferenceCalculation, but this is plain random
+ final String[] parts = soundingId.split(";");
+
+ final BedHeightsArtifact artifact = (BedHeightsArtifact) RiverUtils.getArtifact(parts[0], context);
+
+ final Integer bedheightId = artifact.getDataAsInteger("height_id");
+ // FIXME: this only works with type 'single'; unclear on how to distinguish from epoch data (or whatever the other type means)
+ // Luckily, the requirement is to only access 'single' data here.
+ // final String bedheightType = artifact.getDataAsString("type");
+
+ // FIXME: BedDifferences uses this, but we also need the metadata of the BedHeight
+ // FIXME: second absolutely awful thing: BedHeight is a hibernate binding class, accessing the database via hibernate stuff
+ // BedHeightFactory uses its own (direct) way of accessing the data, with its own implemented data classes.
+ //return BedHeightFactory.getHeight(bedheightType, bedheightId, from, to);
+
+ return BedHeight.getBedHeightById(bedheightId);
+ }
+}
\ No newline at end of file
diff -r 0862ea5d66ba -r 28df64078f27 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculationResult.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculationResult.java Fri Jan 19 11:23:42 2018 +0100
@@ -0,0 +1,68 @@
+/* Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
+ * Software engineering by
+ * Björnsen Beratende Ingenieure GmbH
+ * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+package org.dive4elements.river.artifacts.sinfo.flowdepth;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+
+import gnu.trove.TDoubleArrayList;
+
+/**
+ * Contains the results of a {@link FlowDepthCalculation}.
+ *
+ * @author Gernot Belger
+ */
+class FlowDepthCalculationResult
+implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ private final Collection rows = new ArrayList<>();
+
+ private final String wstLabel;
+
+ private final String soundingLabel;
+
+ public FlowDepthCalculationResult(final String wstLabel, final String soundingLabel) {
+ this.wstLabel = wstLabel;
+ this.soundingLabel = soundingLabel;
+ }
+
+ public void addRow(double station, double flowDepth, double flowDepthWithTkh, double tkh, double waterlevel, double discharge, String waterlevelLabel, String gauge, double meanBedHeight, String sondageLabel, String location) {
+ rows.add(new FlowDepthRow(station, flowDepth, flowDepthWithTkh, tkh, waterlevel, discharge, waterlevelLabel, gauge, meanBedHeight, sondageLabel, location));
+ }
+
+ public String getWstLabel() {
+ return this.wstLabel;
+ }
+
+ public String getSoundingLabel() {
+ return this.soundingLabel;
+ }
+
+ public Collection getRows() {
+ return Collections.unmodifiableCollection( rows );
+ }
+
+ public double[][] getFlowDepthPoints() {
+
+ TDoubleArrayList xPoints = new TDoubleArrayList(rows.size());
+ TDoubleArrayList yPoints = new TDoubleArrayList(rows.size());
+
+ for (FlowDepthRow row : rows) {
+ xPoints.add(row.getStation());
+ yPoints.add(row.getFlowDepth());
+ }
+
+ return new double[][] { xPoints.toNativeArray(), yPoints.toNativeArray() };
+ }
+}
\ No newline at end of file
diff -r 0862ea5d66ba -r 28df64078f27 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculationResults.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculationResults.java Fri Jan 19 11:23:42 2018 +0100
@@ -0,0 +1,63 @@
+/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
+ * Software engineering by
+ * Björnsen Beratende Ingenieure GmbH
+ * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+package org.dive4elements.river.artifacts.sinfo.flowdepth;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.dive4elements.river.model.River;
+
+/**
+ * @author Gernot Belger
+ *
+ */
+public class FlowDepthCalculationResults{
+ private final List results = new ArrayList<>();
+
+ private final River river;
+
+ private final double from;
+
+ private final double to;
+
+ private final boolean useTkh;
+
+ public FlowDepthCalculationResults(final River river, final double from, final double to, final boolean useTkh) {
+ this.river = river;
+ this.from = from;
+ this.to = to;
+ this.useTkh = useTkh;
+ }
+
+ public River getRiver() {
+ return this.river;
+ }
+
+ public double getFrom() {
+ return this.from;
+ }
+
+ public double getTo() {
+ return this.to;
+ }
+
+ public boolean isUseTkh() {
+ return this.useTkh;
+ }
+
+ void addResult(final FlowDepthCalculationResult result) {
+ results.add(result);
+ }
+
+ public List getResults() {
+ return Collections.unmodifiableList(results);
+ }
+}
diff -r 0862ea5d66ba -r 28df64078f27 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthExporter.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthExporter.java Fri Jan 19 11:23:42 2018 +0100
@@ -0,0 +1,449 @@
+/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
+ * Software engineering by Intevation GmbH
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+
+package org.dive4elements.river.artifacts.sinfo.flowdepth;
+
+import java.io.OutputStream;
+import java.text.DateFormat;
+import java.text.NumberFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+import org.dive4elements.artifacts.CallMeta;
+import org.dive4elements.artifacts.common.utils.Config;
+import org.dive4elements.river.artifacts.model.CalculationResult;
+import org.dive4elements.river.artifacts.resources.Resources;
+import org.dive4elements.river.artifacts.sinfo.util.MetaAndTableJRDataSource;
+import org.dive4elements.river.exports.AbstractExporter;
+import org.dive4elements.river.model.River;
+import org.dive4elements.river.utils.Formatter;
+
+import au.com.bytecode.opencsv.CSVWriter;
+import net.sf.jasperreports.engine.JRDataSource;
+import net.sf.jasperreports.engine.JRException;
+import net.sf.jasperreports.engine.JasperExportManager;
+import net.sf.jasperreports.engine.JasperFillManager;
+import net.sf.jasperreports.engine.JasperPrint;
+
+/**
+ * Generates different output formats (csv, pdf) of data that resulted from a flow depths computation.
+ *
+ * @author Ingo Weinzierl
+ * @author Gernot Belger
+ */
+// REMARK: must be public because its registered in generators.xml
+public class FlowDepthExporter extends AbstractExporter {
+
+ /** The log used in this exporter.*/
+ private static Logger log = Logger.getLogger(FlowDepthExporter.class);
+
+ private static final String CSV_KM_HEADER = "sinfo.export.flow_depth.csv.header.km";
+ private static final String CSV_FLOWDEPTH_HEADER = "sinfo.export.flow_depth.csv.header.flowdepth";
+ private static final String CSV_FLOWDEPTHTKH_HEADER = "sinfo.export.flow_depth.csv.header.flowdepthTkh";
+ private static final String CSV_TKH_HEADER = "sinfo.export.flow_depth.csv.header.tkh";
+ private static final String CSV_WATERLEVEL_HEADER = "sinfo.export.flow_depth.csv.header.waterlevel";
+ private static final String CSV_DISCHARGE_HEADER = "sinfo.export.flow_depth.csv.header.discharge";
+ private static final String CSV_LABEL_HEADER = "sinfo.export.flow_depth.csv.header.label";
+ private static final String CSV_GAUGE_HEADER = "sinfo.export.flow_depth.csv.header.gauge";
+ private static final String CSV_MEAN_BED_HEIGHT_HEADER = "sinfo.export.flow_depth.csv.header.mean_bed_height";
+ private static final String CSV_SOUNDING_HEADER = "sinfo.export.flow_depth.csv.header.sounding";
+ private static final String CSV_LOCATION_HEADER = "sinfo.export.flow_depth.csv.header.location";
+
+ private static final String CSV_META_HEADER_RESULT =
+ "sinfo.export.flow_depth.csv.meta.header.result";
+
+ private static final String CSV_META_VERSION =
+ "sinfo.export.flow_depth.csv.meta.version";
+
+ private static final String CSV_META_USER =
+ "sinfo.export.flow_depth.csv.meta.user";
+
+ private static final String CSV_META_CREATION =
+ "sinfo.export.flow_depth.csv.meta.creation";
+
+ private static final String CSV_META_RIVER =
+ "sinfo.export.flow_depth.csv.meta.river";
+
+ private static final String CSV_META_HEADER_SOUNDING =
+ "sinfo.export.flow_depth.csv.meta.header.sounding";
+
+ private static final String CSV_META_HEADER_WATERLEVEL =
+ "sinfo.export.flow_depth.csv.meta.header.waterlevel";
+
+ private static final String JASPER_FILE = "/jasper/sinfo.flowdepth.jasper"; //$NON-NLS-1$
+
+ /** The storage that contains the current calculation result.*/
+ private FlowDepthCalculationResults data = null;
+
+ private NumberFormat meanBedHeightFormatter;
+
+ private NumberFormat tkhFormatter;
+
+ private NumberFormat flowDepthFormatter;
+
+ private NumberFormat getMeanBedHeightFormatter() {
+ if( meanBedHeightFormatter == null )
+ // FIXME: check if this is right
+ meanBedHeightFormatter = Formatter.getMiddleBedHeightHeight(context);
+ return meanBedHeightFormatter;
+ }
+
+ private NumberFormat getTkhFormatter() {
+ if( tkhFormatter == null )
+ // FIXME: check if this is right, probably not, we need one digit
+ tkhFormatter = Formatter.getWaterlevelW(context);
+ return tkhFormatter;
+ }
+
+ private NumberFormat getFlowDepthFormatter() {
+ if( flowDepthFormatter == null )
+ // FIXME: check if this is right
+ flowDepthFormatter = Formatter.getMeterFormat(context);
+ return flowDepthFormatter;
+ }
+
+ @Override
+ protected void addData(Object d) {
+ /* reset */
+ data = null;
+
+ if (d instanceof CalculationResult) {
+
+ final Object dat = ((CalculationResult)d).getData();
+ if( dat != null )
+ data = (FlowDepthCalculationResults)dat;
+ }
+ }
+
+ @Override
+ protected void writeCSVData(CSVWriter writer) {
+ log.info("FlowDepthExporter.writeCSVData");
+
+ /* fetch calculation results */
+ final FlowDepthCalculationResults results = data;
+
+ /* write as csv */
+
+// boolean atGauge = mode == WQ_MODE.QGAUGE || mode == WQ_MODE.WGAUGE;
+// boolean isQ = mode == WQ_MODE.QGAUGE || mode == WQ_MODE.QFREE;
+// RiverUtils.WQ_INPUT input
+// = RiverUtils.getWQInputMode((D4EArtifact)master);
+
+ final boolean useTkh = results.isUseTkh();
+
+ writeCSVMeta(writer, results);
+ writeCSVHeader(writer, useTkh);
+
+ for (final FlowDepthCalculationResult result : results.getResults()) {
+ writeCSVFlowDepthResult(writer, result, useTkh);
+ }
+ }
+
+ private void writeCSVFlowDepthResult(final CSVWriter writer, final FlowDepthCalculationResult result, final boolean useTkh) {
+ final Collection rows = result.getRows();
+ for (final FlowDepthRow flowDepthRow : rows) {
+ writeCSVFlowDepthRow(writer, flowDepthRow, useTkh);
+ }
+ }
+
+ private void writeCSVMeta(final CSVWriter writer, final FlowDepthCalculationResults results) {
+ log.info("FlowDepthExporter.writeCSVMeta");
+
+ // Workflow zur Berechnung der Fließtiefe.pdf
+ // "##ERGEBNISAUSGABE - Name des Gewässers - Fließtiefe"
+ final River river = results.getRiver();
+ writeCSVMeataEntry(writer, CSV_META_HEADER_RESULT, river.getName() );
+
+ // "# FLYS-Version: "
+ // FIXME
+ final String flysVersion = "unbekannt";
+ writeCSVMeataEntry(writer, CSV_META_VERSION, flysVersion );
+
+ // "# Bearbeiter: "
+ // FIXME
+ final String user = "unbekannt";
+ writeCSVMeataEntry(writer, CSV_META_USER, user );
+
+ // "# Datum der Erstellung: "
+ final Locale locale = Resources.getLocale(context.getMeta());
+ final DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, locale);
+ writeCSVMeataEntry(writer, CSV_META_CREATION, df.format(new Date()) );
+
+ // "# Gewässer: "
+ writeCSVMeataEntry(writer, CSV_META_RIVER, river.getName() );
+
+ // "# Höhensystem des Flusses: "
+
+ // FIXME
+
+ // "# Ort/Bereich (km): "
+ // FIXME
+ // TODO: unklar, es wird nur ein Bereich eingegeben
+// RangeAccess rangeAccess = new RangeAccess(flys);
+// double[] kms = rangeAccess.getKmRange();
+// writer.writeNext(new String[] {
+// Resources.getMsg(
+// meta,
+// CSV_META_RANGE,
+// CSV_META_RANGE,
+// new Object[] { kms[0], kms[kms.length-1] })
+// });
+
+ // "##METADATEN PEILUNG"
+ writeCSVMeataEntry(writer, CSV_META_HEADER_SOUNDING );
+
+// "# Jahr der Peilung: "
+ // FIXME
+// "# Aufnahmeart: "
+ // FIXME
+// "# Lagesystem: "
+ // FIXME
+// "# Höhensystem: "
+ // FIXME
+// "# ursprüngliches Höhensystem: "
+ // FIXME
+// "##METADATEN WASSERSPIEGELLAGE"
+ writeCSVMeataEntry(writer, CSV_META_HEADER_WATERLEVEL );
+// "# Bezeichnung der Wasserspiegellage: "
+ // FIXME
+// "# Höhensystem der Wasserspiegellage: "
+ // FIXME
+// "# Auswerter: "
+ // FIXME
+// "# Bezugspegel: "
+ // FIXME
+// "# Jahr/Zeitraum der Wasserspiegellage: "
+ // FIXME
+
+ // "# W/Pegel [cm]: " (nur bei Eingabe des Wasserstands am Pegel)
+ // TODO: unklar, es wird kein W eingegeben
+
+ // "# Q (m³/s): " (nur bei Eingabe des Durchflusses)
+ // TODO: unklar, es wird kein Q eingegeben
+
+// writer.writeNext(new String[] {
+// Resources.getMsg(
+// meta,
+// CSV_META_GAUGE,
+// CSV_META_GAUGE,
+// new Object[] { RiverUtils.getGaugename(flys) })
+// });
+
+ writer.writeNext(new String[] { "" });
+ }
+
+
+ private void writeCSVMeataEntry(CSVWriter writer, String message, Object... messageArgs) {
+
+ CallMeta meta = context.getMeta();
+
+ writer.writeNext(new String[] {
+ Resources.getMsg(
+ meta,
+ message,
+ message,
+ messageArgs)
+ });
+ }
+
+ /**
+ * Write the header, with different headings depending on whether at a
+ * gauge or at a location.
+ * @param useTkh
+ */
+ private void writeCSVHeader(
+ final CSVWriter writer,
+ final boolean useTkh
+ ) {
+ log.info("FlowDepthExporter.writeCSVHeader");
+
+ final Collection header = new ArrayList<>(11);
+
+ header.add(msg(CSV_KM_HEADER,CSV_KM_HEADER));
+ header.add(msg(CSV_FLOWDEPTH_HEADER));
+ if( useTkh )
+ {
+ header.add(msg(CSV_FLOWDEPTHTKH_HEADER));
+ header.add(msg(CSV_TKH_HEADER));
+ }
+ header.add(msg(CSV_WATERLEVEL_HEADER));
+ header.add(msg(CSV_DISCHARGE_HEADER));
+ header.add(msg(CSV_LABEL_HEADER));
+ header.add(msg(CSV_GAUGE_HEADER));
+ header.add(msg(CSV_MEAN_BED_HEIGHT_HEADER));
+ header.add(msg(CSV_SOUNDING_HEADER));
+ header.add(msg(CSV_LOCATION_HEADER));
+
+ writer.writeNext(header.toArray(new String[header.size()]));
+ }
+
+ /**
+ * Format a row of a flow depth result into an array of string, both used by csv and pdf
+ * @param useTkh
+ */
+ private String[] formatFlowDepthRow(
+ final FlowDepthRow row,
+ boolean useTkh ) {
+
+ final Collection lines = new ArrayList<>(11);
+
+ // Fluss-km
+ lines.add( getKmFormatter().format( row.getStation() ) );
+
+ // Fließtiefe [m]
+ lines.add( getFlowDepthFormatter().format( row.getFlowDepth() ) );
+
+ if( useTkh )
+ {
+ // Fließtiefe mit TKH [m]
+ lines.add( getFlowDepthFormatter().format( row.getFlowDepthWithTkh() ) );
+
+ // TKH [cm]
+ lines.add( getTkhFormatter().format( row.getTkh() ) );
+ }
+
+ // Wasserstand [NN + m]
+ lines.add( getWFormatter().format( row.getWaterlevel() ) );
+
+ // Q [m³/s]
+ lines.add( getQFormatter().format( row.getDischarge() ) );
+
+ // Bezeichnung
+ lines.add( row.getWaterlevelLabel() );
+
+ // Bezugspegel
+ lines.add( row.getGauge() );
+
+ // Mittlere Sohlhöhe [NN + m]
+ lines.add( getMeanBedHeightFormatter().format( row.getMeanBedHeight( ) ) );
+
+ // Peilung/Epoche
+ lines.add( row.getSoundageLabel() );
+
+ // Lage
+ lines.add( row.getLocation() );
+
+ return lines.toArray(new String[lines.size()]);
+ }
+ /**
+ * Write "rows" of csv data from wqkms with writer.
+ * @param useTkh
+ */
+ private void writeCSVFlowDepthRow(
+ final CSVWriter writer,
+ final FlowDepthRow row,
+ final boolean useTkh
+ ) {
+ log.debug("FlowDepthExporter.writeCSVFlowDepthRow");
+
+ final String[] formattedRow = formatFlowDepthRow(row, useTkh);
+ writer.writeNext( formattedRow );
+ }
+
+ @Override
+ protected void writePDF(OutputStream outStream) {
+ log.debug("write PDF");
+
+ final JRDataSource source = createJRData();
+
+ final String confPath = Config.getConfigDirectory().toString();
+
+ // FIXME: distinguish between with and without tkh: we need two jasper reports!
+
+ final Map parameters = new HashMap<>();
+ parameters.put("ReportTitle", "Exported Data");
+ try {
+ final JasperPrint print = JasperFillManager.fillReport(
+ confPath + JASPER_FILE,
+ parameters,
+ source);
+ JasperExportManager.exportReportToPdfStream(print, outStream);
+ }
+ catch(JRException je) {
+ log.warn("Error generating PDF Report!", je);
+ }
+ }
+
+ private JRDataSource createJRData() {
+
+ /* fetch calculation results */
+ final FlowDepthCalculationResults results = data;
+
+ final MetaAndTableJRDataSource source = new MetaAndTableJRDataSource();
+
+ addJRMetaData(source, results);
+
+ final boolean useTkh = results.isUseTkh();
+
+ for (final FlowDepthCalculationResult result : results.getResults()) {
+ addJRTableData(source, result, useTkh);
+ }
+
+ return source;
+ }
+
+ private void addJRMetaData(final MetaAndTableJRDataSource source, FlowDepthCalculationResults results) {
+
+ // Workflow zur Berechnung der Fließtiefe.pdf
+ // "##ERGEBNISAUSGABE - Name des Gewässers - Fließtiefe"
+ // writeCSVMeataEntry(writer, CSV_META_HEADER_RESULT, inputData.getRiver() );
+
+ // FIXME
+ final String flysVersion = "unbekannt";
+ // CSV_META_VERSION
+ source.addMetaData("version", flysVersion);
+
+ // FIXME
+ String user = "unbekannt";
+ // CSV_META_USER
+ source.addMetaData("user", user);
+
+ final Locale locale = Resources.getLocale(context.getMeta());
+ final DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, locale);
+ source.addMetaData("date", df.format(new Date()));
+
+ // CSV_META_RIVER
+ source.addMetaData("river", results.getRiver().getName());
+
+ // FIXME
+ source.addMetaData("range", "FIXME");
+ // "# Ort/Bereich (km): "
+ // FIXME
+ // TODO: unklar, es wird nur ein Bereich eingegeben
+// RangeAccess rangeAccess = new RangeAccess(flys);
+// double[] kms = rangeAccess.getKmRange();
+// writer.writeNext(new String[] {
+// Resources.getMsg(
+// meta,
+// CSV_META_RANGE,
+// CSV_META_RANGE,
+// new Object[] { kms[0], kms[kms.length-1] })
+// });
+
+// RangeAccess rangeAccess = new RangeAccess(flys);
+// double[] kms = rangeAccess.getKmRange();
+// source.addMetaData("range",
+// kmf.format(kms[0]) + " - " + kmf.format(kms[kms.length-1]));
+ }
+
+ private void addJRTableData(final MetaAndTableJRDataSource source, final FlowDepthCalculationResult result, final boolean useTkh) {
+
+ final Collection rows = result.getRows();
+
+ for (final FlowDepthRow row : rows) {
+
+ final String[] formattedRow = formatFlowDepthRow(row, useTkh);
+ source.addData(formattedRow);
+ }
+ }
+}
\ No newline at end of file
diff -r 0862ea5d66ba -r 28df64078f27 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthFilterFacet.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthFilterFacet.java Fri Jan 19 11:23:42 2018 +0100
@@ -0,0 +1,98 @@
+/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
+ * Software engineering by Intevation GmbH
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+
+package org.dive4elements.river.artifacts.sinfo.flowdepth;
+
+import org.apache.log4j.Logger;
+import org.dive4elements.artifactdatabase.state.Facet;
+import org.dive4elements.artifacts.Artifact;
+import org.dive4elements.artifacts.CallContext;
+import org.dive4elements.river.artifacts.D4EArtifact;
+import org.dive4elements.river.artifacts.model.CalculationResult;
+import org.dive4elements.river.artifacts.model.DataFacet;
+import org.dive4elements.river.artifacts.states.DefaultState.ComputeType;
+
+/**
+ * Facet of a FlowDepth curve.
+ */
+public class FlowDepthFilterFacet extends DataFacet {
+
+ private static Logger log = Logger.getLogger(FlowDepthFilterFacet.class);
+
+ public FlowDepthFilterFacet() {
+ // required for clone operation deepCopy()
+ }
+
+ public FlowDepthFilterFacet(
+ int idx,
+ String name,
+ String description,
+ ComputeType type,
+ String stateId,
+ String hash
+ ) {
+ super(idx, name, description, type, hash, stateId);
+ this.metaData.put("X", "sinfo.chart.flow_depth.xaxis.label");
+ this.metaData.put("Y", "sinfo.chart.flow_depth.yaxis.label");
+ }
+
+ @Override
+ public Object getData(Artifact artifact, CallContext context) {
+ log.debug("Get data for flow velocity at index: " + index);
+
+ final D4EArtifact flys = (D4EArtifact) artifact;
+
+ final CalculationResult res = (CalculationResult)
+ flys.compute(context, hash, stateId, type, false);
+
+ final FlowDepthCalculationResults data = (FlowDepthCalculationResults) res.getData();
+
+ final FlowDepthCalculationResult result = data.getResults().get(index);
+
+ // FIXME: variable mean computation depending on current scale
+// Double start = (Double)context.getContextValue("startkm");
+// Double end = (Double)context.getContextValue("endkm");
+// if(start != null && end != null) {
+// RiverContext fc = (RiverContext)context.globalContext();
+// ZoomScale scales = (ZoomScale)fc.get("zoomscale");
+// RiverAccess access = new RiverAccess((D4EArtifact)artifact);
+// String river = access.getRiverName();
+//
+// double radius = scales.getRadius(river, start, end);
+// FlowVelocityData oldData = data[index];
+// FlowVelocityData newData = new FlowVelocityData();
+// double[][] q = oldData.getQPoints();
+// double[][] totalV = MovingAverage.weighted(oldData.getTotalChannelPoints(), radius);
+// double[][] mainV = MovingAverage.weighted(oldData.getMainChannelPoints(), radius);
+// double[][] tau = MovingAverage.weighted(oldData.getTauPoints(), radius);
+// for(int j = 0; j < q[0].length; j++) {
+// newData.addKM(q[0][j]);
+// newData.addQ(q[1][j]);
+// newData.addTauMain(tau[1][j]);
+// newData.addVMain(mainV[1][j]);
+// newData.addVTotal(totalV[1][j]);
+// }
+// return newData;
+// }
+
+ return result;
+ }
+
+
+ /** Copy deeply. */
+ @Override
+ public Facet deepCopy() {
+ FlowDepthFilterFacet copy = new FlowDepthFilterFacet();
+ // FIXME: why does DataFacet does not override set? Bad access to variables of parent!
+ copy.set(this);
+ copy.type = type;
+ copy.hash = hash;
+ copy.stateId = stateId;
+ return copy;
+ }
+}
\ No newline at end of file
diff -r 0862ea5d66ba -r 28df64078f27 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthPairSelectState.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthPairSelectState.java Fri Jan 19 11:23:42 2018 +0100
@@ -0,0 +1,27 @@
+/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
+ * Software engineering by
+ * Björnsen Beratende Ingenieure GmbH
+ * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+package org.dive4elements.river.artifacts.sinfo.flowdepth;
+
+import org.dive4elements.river.artifacts.states.WaterlevelPairSelectState;
+
+/**
+ * @author Gernot Belger
+ *
+ */
+public class FlowDepthPairSelectState
+// FIXME: very ugly; but probably we will break the serialization of WaterlevelPairSelectState if we introduce an abstraction
+extends WaterlevelPairSelectState {
+
+ /** Specify to display a datacage_twin_panel. */
+ @Override
+ protected String getUIProvider() {
+ return "sinfo_flowdepth_twin_panel";
+ }
+}
diff -r 0862ea5d66ba -r 28df64078f27 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthProcessor.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthProcessor.java Fri Jan 19 11:23:42 2018 +0100
@@ -0,0 +1,105 @@
+/* Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
+ * Software engineering by
+ * Björnsen Beratende Ingenieure GmbH
+ * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+
+package org.dive4elements.river.artifacts.sinfo.flowdepth;
+
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+import org.dive4elements.artifactdatabase.state.ArtifactAndFacet;
+import org.dive4elements.artifacts.CallContext;
+import org.dive4elements.river.exports.DiagramGenerator;
+import org.dive4elements.river.exports.StyledSeriesBuilder;
+import org.dive4elements.river.exports.process.DefaultProcessor;
+import org.dive4elements.river.jfree.StyledXYSeries;
+import org.dive4elements.river.themes.ThemeDocument;
+
+public final class FlowDepthProcessor extends DefaultProcessor {
+
+ /* Theme name, usually defined in 'FacetTypes', but that is soooo bad dependencies... */
+ static String FACET_FLOW_DEPTH_FILTERED = "sinfo_flow_depth.filtered";
+
+ private final static Logger log = Logger.getLogger(FlowDepthProcessor.class);
+
+ private static final String I18N_AXIS_LABEL = "sinfo.chart.flow_depth.section.yaxis.label";
+ private String yAxisLabel;
+
+ @Override
+ public void doOut(
+ final DiagramGenerator generator,
+ final ArtifactAndFacet bundle,
+ final ThemeDocument theme,
+ final boolean visible) {
+
+ final CallContext context = generator.getCallContext();
+ final Map metaData = bundle.getFacet().getMetaData();
+
+ final StyledXYSeries series = new StyledXYSeries(bundle.getFacetDescription(), theme);
+ series.putMetaData(metaData, bundle.getArtifact(), context);
+
+ yAxisLabel = metaData.get("Y");
+
+ final String facetName = bundle.getFacetName();
+ final FlowDepthCalculationResult data = (FlowDepthCalculationResult) bundle.getData(context);
+ if (data == null) {
+ // Check has been here before so we keep it for security reasons
+ // this should never happen though.
+ log.error("Data is null for facet: " + facetName);
+ return;
+ }
+
+ final double [][] points = generatePoints(data);
+
+ StyledSeriesBuilder.addPoints(series, points, true);
+ generator.addAxisSeries(series, axisName, visible);
+ }
+
+ private static double[][] generatePoints(final FlowDepthCalculationResult data) {
+
+ // FIXME
+ return data.getFlowDepthPoints();
+
+// if (facetName.equals(FacetTypes.FLOW_VELOCITY_TOTALCHANNEL) ||
+// facetName.equals(FacetTypes.FLOW_VELOCITY_TOTALCHANNEL_FILTERED)) {
+// FlowVelocityData fData = (FlowVelocityData) data;
+// points = fData.getTotalChannelPoints();
+// } else if (facetName.equals(FacetTypes.FLOW_VELOCITY_MAINCHANNEL) ||
+// facetName.equals(FacetTypes.FLOW_VELOCITY_MAINCHANNEL_FILTERED)) {
+// FlowVelocityData fData = (FlowVelocityData) data;
+// points = fData.getMainChannelPoints(); // I hate facets!
+// } else if (facetName.equals(FacetTypes.FLOW_VELOCITY_MEASUREMENT)) {
+// FastFlowVelocityMeasurementValue fData =
+// (FastFlowVelocityMeasurementValue) data;
+// points = new double[][] {{fData.getStation()},{fData.getV()}};
+// } else {
+// log.error("Unknown facet name: " + facetName);
+// return;
+// }
+ }
+
+ @Override
+ public boolean canHandle(String facettype) {
+ return FACET_FLOW_DEPTH_FILTERED.equals(facettype);
+ }
+
+ @Override
+ public String getAxisLabel(DiagramGenerator generator) {
+ if (yAxisLabel != null && !yAxisLabel.isEmpty()) {
+ // REMARK/UNINTENDED: yAxisLabel may also be a resolved message (side-effect of StyledXYSeries#putMetadata),
+ // and cannot be resolved, so we need to give the resolved value as default
+ // In other implementations (i.e. FlowVelocityProcessor), an explicit (German) default label is given here, probably
+ // the English version will also show German (CHECK)
+ return generator.msg(yAxisLabel, yAxisLabel);
+ }
+ return generator.msg(
+ I18N_AXIS_LABEL,
+ "MISSING");
+ }
+}
\ No newline at end of file
diff -r 0862ea5d66ba -r 28df64078f27 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthRow.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthRow.java Fri Jan 19 11:23:42 2018 +0100
@@ -0,0 +1,90 @@
+/* Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
+ * Software engineering by
+ * Björnsen Beratende Ingenieure GmbH
+ * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+package org.dive4elements.river.artifacts.sinfo.flowdepth;
+
+import java.io.Serializable;
+
+/**
+ * Part of {@link FlowDepthCalculationResult} which represents one calculated row of flow depth data.
+ *
+ * @author Gernot Belger
+ */
+final class FlowDepthRow
+implements Serializable {
+ private final double station;
+ private final double flowDepth;
+ private final double flowDepthWithTkh;
+ private final double tkh;
+ private final double waterlevel;
+ private final double discharge;
+ private final String waterlevelLabel;
+ private final String gauge;
+ private final double meanBedHeight;
+ private final String soundageLabel;
+ private final String location;
+
+ public FlowDepthRow( double station, double flowDepth, double flowDepthWithTkh, double tkh, double waterlevel, double discharge, String waterlevelLabel, String gauge, double meanBedHeight, String soundageLabel, String location ) {
+ this.station = station;
+ this.flowDepth = flowDepth;
+ this.flowDepthWithTkh = flowDepthWithTkh;
+ this.tkh = tkh;
+ this.waterlevel = waterlevel;
+ this.discharge = discharge;
+ this.waterlevelLabel = waterlevelLabel;
+ this.gauge = gauge;
+ this.meanBedHeight = meanBedHeight;
+ this.soundageLabel = soundageLabel;
+ this.location = location;
+ }
+
+ public double getStation() {
+ return station;
+ }
+
+ public double getFlowDepth() {
+ return flowDepth;
+ }
+
+ public double getFlowDepthWithTkh() {
+ return flowDepthWithTkh;
+ }
+
+ public double getTkh() {
+ return tkh;
+ }
+
+ public double getWaterlevel() {
+ return waterlevel;
+ }
+
+ public double getDischarge() {
+ return discharge;
+ }
+
+ public String getWaterlevelLabel() {
+ return waterlevelLabel;
+ }
+
+ public String getGauge() {
+ return gauge;
+ }
+
+ public double getMeanBedHeight() {
+ return meanBedHeight;
+ }
+
+ public String getSoundageLabel() {
+ return soundageLabel;
+ }
+
+ public String getLocation() {
+ return location;
+ }
+}
\ No newline at end of file
diff -r 0862ea5d66ba -r 28df64078f27 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthState.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthState.java Fri Jan 19 11:23:42 2018 +0100
@@ -0,0 +1,140 @@
+/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
+ * Software engineering by Intevation GmbH
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+
+package org.dive4elements.river.artifacts.sinfo.flowdepth;
+
+import java.util.List;
+
+import org.dive4elements.artifactdatabase.state.Facet;
+import org.dive4elements.artifacts.CallContext;
+import org.dive4elements.river.artifacts.ChartArtifact;
+import org.dive4elements.river.artifacts.D4EArtifact;
+import org.dive4elements.river.artifacts.model.Calculation;
+import org.dive4elements.river.artifacts.model.CalculationResult;
+import org.dive4elements.river.artifacts.model.DataFacet;
+import org.dive4elements.river.artifacts.model.EmptyFacet;
+import org.dive4elements.river.artifacts.model.FacetTypes;
+import org.dive4elements.river.artifacts.model.ReportFacet;
+import org.dive4elements.river.artifacts.resources.Resources;
+import org.dive4elements.river.artifacts.sinfo.SINFOArtifact;
+import org.dive4elements.river.artifacts.states.DefaultState;
+
+/** State in which a waterlevel has been calculated. */
+public class FlowDepthState
+extends DefaultState
+{
+ /// ** The log that is used in this state. */
+ // private static Logger log = Logger.getLogger(FlowDepthState.class);
+
+ private static final String I18N_FACET_FLOW_DEPTH_FILTERED_DESCRIPTION = "sinfo.facet.flow_depth.filtered.description";
+
+ /**
+ * From this state can only be continued trivially.
+ */
+ @Override
+ protected String getUIProvider() {
+ return "continue";
+ }
+
+ @Override
+ public Object computeFeed(
+ final D4EArtifact artifact,
+ final String hash,
+ final CallContext context,
+ final List facets,
+ final Object old
+ ) {
+ // FIXME: why is this necessary?
+ if (artifact instanceof ChartArtifact) {
+ facets.add(new EmptyFacet());
+ return null;
+ }
+ return compute((SINFOArtifact) artifact, context, hash, facets, old);
+ }
+
+ @Override
+ public Object computeAdvance(
+ final D4EArtifact artifact,
+ final String hash,
+ final CallContext context,
+ final List facets,
+ final Object old
+ ) {
+ if (artifact instanceof ChartArtifact) {
+ facets.add(new EmptyFacet());
+ return null;
+ }
+ return compute((SINFOArtifact) artifact, context, hash, facets, old);
+ }
+
+ /**
+ * Compute result or returned object from cache, create facets.
+ * @param old Object that was cached.
+ */
+ private Object compute(
+ final SINFOArtifact sinfo,
+ final CallContext context,
+ final String hash,
+ final List facets,
+ final Object old
+ ) {
+ final CalculationResult res;
+ if (old instanceof CalculationResult)
+ res = (CalculationResult) old;
+ else
+ res = new FlowDepthCalculation(context).calculate(sinfo);
+
+ if (facets == null) {
+ return res;
+ }
+
+ final FlowDepthCalculationResults results = (FlowDepthCalculationResults) res.getData();
+
+ /* add themes for chart, for each result */
+ final List resultList = results.getResults();
+ for (int index = 0; index < resultList.size(); index++) {
+
+ final FlowDepthCalculationResult result = resultList.get(index);
+ /* compute theme label */
+ final String wspLabel = result.getWstLabel();
+ final String soundingLabel = result.getSoundingLabel();
+ final String inputLabel = String.format("%s - %s", wspLabel, soundingLabel);
+
+ /* filtered (zoom dependent mean) flow depth */
+ final String facetFlowDepthFilteredDescription = Resources.getMsg( context.getMeta(), I18N_FACET_FLOW_DEPTH_FILTERED_DESCRIPTION, I18N_FACET_FLOW_DEPTH_FILTERED_DESCRIPTION, inputLabel );
+ facets.add(new FlowDepthFilterFacet(
+ index,
+ FlowDepthProcessor.FACET_FLOW_DEPTH_FILTERED,
+ facetFlowDepthFilteredDescription,
+ ComputeType.ADVANCE,
+ id,
+ hash
+ ));
+
+ // FIXME: add other themes
+ }
+
+ if (!resultList.isEmpty() ) {
+ Facet csv = new DataFacet(
+ FacetTypes.CSV, "CSV data", ComputeType.ADVANCE, hash, id);
+ Facet pdf = new DataFacet(
+ FacetTypes.PDF, "PDF data", ComputeType.ADVANCE, hash, id);
+
+ facets.add(csv);
+ facets.add(pdf);
+ }
+
+ final Calculation report = res.getReport();
+
+ if (report.hasProblems()) {
+ facets.add(new ReportFacet(ComputeType.ADVANCE, hash, id));
+ }
+
+ return res;
+ }
+}
\ No newline at end of file
diff -r 0862ea5d66ba -r 28df64078f27 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/UseTransportBodiesChoice.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/UseTransportBodiesChoice.java Fri Jan 19 11:23:42 2018 +0100
@@ -0,0 +1,21 @@
+/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
+ * Software engineering by Intevation GmbH
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+
+package org.dive4elements.river.artifacts.sinfo.flowdepth;
+
+import org.dive4elements.river.artifacts.states.BooleanChoiceState;
+
+/**
+ * @author Ingo Weinzierl
+ */
+public class UseTransportBodiesChoice extends BooleanChoiceState {
+
+ public UseTransportBodiesChoice() {
+ super( "useTransportBodies.option", "useTransportBodies.active", "useTransportBodies.inactive" );
+ }
+}
\ No newline at end of file
diff -r 0862ea5d66ba -r 28df64078f27 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/util/MetaAndTableJRDataSource.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/util/MetaAndTableJRDataSource.java Fri Jan 19 11:23:42 2018 +0100
@@ -0,0 +1,64 @@
+/* Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
+ * Software engineering by
+ * Björnsen Beratende Ingenieure GmbH
+ * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+package org.dive4elements.river.artifacts.sinfo.util;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import net.sf.jasperreports.engine.JRDataSource;
+import net.sf.jasperreports.engine.JRException;
+import net.sf.jasperreports.engine.JRField;
+
+/**
+ * @author Raimund Renkert
+ */
+public final class MetaAndTableJRDataSource implements JRDataSource
+{
+ private List data = new ArrayList<>();
+
+ private Map metaData = new HashMap<>();
+
+ private int index = -1;
+
+ public void addData(final String[] data) {
+ this.data.add(data);
+ }
+
+ public void addMetaData(final String key, final String value) {
+ this.metaData.put(key, value);
+ }
+
+ @Override
+ public boolean next() throws JRException
+ {
+ index++;
+
+ return index < data.size();
+ }
+
+ @Override
+ public Object getFieldValue(final JRField field) throws JRException
+ {
+ final String fieldName = field.getName();
+
+ if( fieldName.startsWith("meta:"))
+ return metaData.get(fieldName.substring("meta:".length()));
+
+ if( fieldName.startsWith("data:"))
+ {
+ int column = Integer.valueOf(fieldName.substring("data:".length()));
+ return data.get(index)[column];
+ }
+
+ return null;
+ }
+}
\ No newline at end of file
diff -r 0862ea5d66ba -r 28df64078f27 artifacts/src/main/java/org/dive4elements/river/artifacts/states/BooleanChoiceState.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/states/BooleanChoiceState.java Fri Jan 19 11:23:42 2018 +0100
@@ -0,0 +1,100 @@
+/* Copyright (C) 2011, 2012, 2017 by Bundesanstalt für Gewässerkunde
+ * Software engineering by Intevation GmbH
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+package org.dive4elements.river.artifacts.states;
+
+import org.w3c.dom.Element;
+
+import org.apache.log4j.Logger;
+
+import org.dive4elements.artifacts.Artifact;
+import org.dive4elements.artifacts.CallContext;
+import org.dive4elements.artifacts.CallMeta;
+
+import org.dive4elements.artifacts.common.utils.XMLUtils;
+
+import org.dive4elements.artifactdatabase.ProtocolUtils;
+
+import org.dive4elements.river.artifacts.resources.Resources;
+
+/**
+ * Generic state for a boolean choice. Only difference between real implementations are the human readable labels.
+ *
+ * @author Ingo Weinzierl
+ * @author Gernot Belger
+ */
+public abstract class BooleanChoiceState extends DefaultState {
+
+ private String optionMsg;
+ private String activeMsg;
+ private String inactiveMsg;
+
+ public BooleanChoiceState( String optionMsg, String activeMsg, String inactiveMsg ) {
+ this.optionMsg = optionMsg;
+ this.activeMsg = activeMsg;
+ this.inactiveMsg = inactiveMsg;
+ }
+
+ private static final Logger log =
+ Logger.getLogger(BooleanChoiceState.class);
+
+ @Override
+ protected String getUIProvider() {
+ return "boolean_panel";
+ }
+
+ @Override
+ protected Element[] createItems(
+ XMLUtils.ElementCreator cr,
+ Artifact artifact,
+ String name,
+ CallContext context)
+ {
+ CallMeta meta = context.getMeta();
+
+ Element option = createItem(
+ cr,
+ new String[] { Resources.getMsg(meta, optionMsg, optionMsg), "true" });
+
+ return new Element[] { option };
+ }
+
+
+ @Override
+ protected String getLabelFor(
+ CallContext cc,
+ String name,
+ String value,
+ String type
+ ) {
+ log.debug("GET LABEL FOR '" + name + "' / '" + value + "'");
+ if (value != null && value.equals("true")) {
+ return Resources.getMsg(cc.getMeta(), activeMsg, activeMsg);
+ }
+ else {
+ return Resources.getMsg(cc.getMeta(), inactiveMsg, inactiveMsg);
+ }
+ }
+
+
+ protected Element createItem(XMLUtils.ElementCreator cr, Object obj) {
+ Element item = ProtocolUtils.createArtNode(cr, "item", null, null);
+ Element label = ProtocolUtils.createArtNode(cr, "label", null, null);
+ Element value = ProtocolUtils.createArtNode(cr, "value", null, null);
+
+ String[] arr = (String[]) obj;
+
+ label.setTextContent(arr[0]);
+ value.setTextContent(arr[1]);
+
+ item.appendChild(label);
+ item.appendChild(value);
+
+ return item;
+ }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :
diff -r 0862ea5d66ba -r 28df64078f27 artifacts/src/main/java/org/dive4elements/river/artifacts/states/FloodplainChoice.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/states/FloodplainChoice.java Thu Jan 18 20:54:03 2018 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/states/FloodplainChoice.java Fri Jan 19 11:23:42 2018 +0100
@@ -26,6 +26,7 @@
/**
* @author Ingo Weinzierl
*/
+// FIXME: inherit from BooleanChoiceState instead to remove duplicate code; BUT: this will probably break artifact serialization
public class FloodplainChoice extends DefaultState {
public static final String OPTION = "floodplain.option";
diff -r 0862ea5d66ba -r 28df64078f27 artifacts/src/main/java/org/dive4elements/river/artifacts/states/WDifferencesState.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/states/WDifferencesState.java Thu Jan 18 20:54:03 2018 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/states/WDifferencesState.java Fri Jan 19 11:23:42 2018 +0100
@@ -109,6 +109,7 @@
/**
* Access the data (wkms) of an artifact, coded in mingle.
*/
+ // FIXME: meanwhile used by several places outside this context; refactor into separate helper class to access waterlevels
public WKms getWKms(
String mingle,
CallContext context,
diff -r 0862ea5d66ba -r 28df64078f27 artifacts/src/main/java/org/dive4elements/river/artifacts/states/WaterlevelPairSelectState.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/states/WaterlevelPairSelectState.java Thu Jan 18 20:54:03 2018 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/states/WaterlevelPairSelectState.java Fri Jan 19 11:23:42 2018 +0100
@@ -48,7 +48,7 @@
/** Specify to display a datacage_twin_panel. */
@Override
protected String getUIProvider() {
- return "datacage_twin_panel";
+ return "waterlevel_twin_panel";
}
diff -r 0862ea5d66ba -r 28df64078f27 artifacts/src/main/java/org/dive4elements/river/exports/process/FlowVelocityProcessor.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/process/FlowVelocityProcessor.java Thu Jan 18 20:54:03 2018 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/process/FlowVelocityProcessor.java Fri Jan 19 11:23:42 2018 +0100
@@ -94,6 +94,9 @@
@Override
public String getAxisLabel(DiagramGenerator generator) {
if (yAxisLabel != null && !yAxisLabel.isEmpty()) {
+ // FIXME/UNINTENDED: yAxisLabel is probably a resolved message (side-effect of StyledXYSeries#putMetadata),
+ // and cannot be resolved again.
+ // An explicit (German) default label is therefore given here, probably the English version will also show German (CHECK)
return generator.msg(yAxisLabel, I18N_AXIS_LABEL_DEFAULT);
}
return generator.msg(
diff -r 0862ea5d66ba -r 28df64078f27 artifacts/src/main/java/org/dive4elements/river/jfree/StyledXYSeries.java
--- a/artifacts/src/main/java/org/dive4elements/river/jfree/StyledXYSeries.java Thu Jan 18 20:54:03 2018 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/jfree/StyledXYSeries.java Fri Jan 19 11:23:42 2018 +0100
@@ -146,6 +146,7 @@
@Override
+ // FIXME: bad! method with undocumented side-effects; given metadata will be changed inline
public void putMetaData(Map metaData,
Artifact artifact,
CallContext context) {
@@ -155,6 +156,7 @@
String unit = "";
if (river != null) {
rivername = river.getName();
+ // FIXME: this will always return the wst unit, regardless if the series is a water level or not!
unit = river.getWstUnit().getName();
}
if (metaData.containsKey("X")) {
diff -r 0862ea5d66ba -r 28df64078f27 artifacts/src/main/java/org/dive4elements/river/utils/GaugeIndex.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/utils/GaugeIndex.java Fri Jan 19 11:23:42 2018 +0100
@@ -0,0 +1,52 @@
+/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
+ * Software engineering by
+ * Björnsen Beratende Ingenieure GmbH
+ * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+package org.dive4elements.river.utils;
+
+import java.util.List;
+
+import org.dive4elements.river.model.Gauge;
+
+/**
+ * Allows performant access to gauges by station.
+ * @author Gernot Belger
+ */
+public class GaugeIndex {
+ private List gauges;
+
+ private Gauge lastGauge = null;
+
+ public GaugeIndex( List gauges) {
+ this.gauges = gauges;
+ }
+
+ public Gauge findGauge(double km) {
+
+ // REMARK: this is code copied from WaterlevelExporter, which is honestly not very fast/good.
+ // Instead we need to index by range with an RTree and directly acccess the right gauge.
+
+ if( lastGauge != null && lastGauge.getRange().contains(km) )
+ return lastGauge;
+
+ final Gauge gauge = findGauge(km, gauges);
+
+ lastGauge = gauge;
+
+ return gauge;
+ }
+
+ private static Gauge findGauge(double km, List gauges) {
+ for (Gauge gauge: gauges) {
+ if (gauge.getRange().contains(km)) {
+ return gauge;
+ }
+ }
+ return null;
+ }
+}
\ No newline at end of file
diff -r 0862ea5d66ba -r 28df64078f27 artifacts/src/main/resources/messages.properties
--- a/artifacts/src/main/resources/messages.properties Thu Jan 18 20:54:03 2018 +0100
+++ b/artifacts/src/main/resources/messages.properties Fri Jan 19 11:23:42 2018 +0100
@@ -761,3 +761,65 @@
help.state.fix.vollmer.preprocessing=${help.url}/OnlineHilfe/Fixierungsanalyse#help.state.fix.vollmer.preprocessing
help.state.fix.vollmer.qs=${help.url}/OnlineHilfe/Fixierungsanalyse#help.state.fix.vollmer.qs
help.state.fix.vollmer.compute=${help.url}/OnlineHilfe/Fixierungsanalyse#help.state.fix.vollmer.compute
+
+state.sinfo.river = River
+state.sinfo.calculation_mode=Calculation Mode
+
+sinfo_calc_flow_depth=Flie\u00dftiefen
+sinfo_calc_flow_depth_development=Flie\u00dftiefenentwicklung
+sinfo_calc_flow_depth_minmax=Minimale und Maximale Flie\u00dftiefe
+sinfo_calc_grounding=Grundber\u00fchrungen
+sinfo_calc_transport_bodies_heights=Transportk\u00f6rperh\u00f6hen
+sinfo_calc_infrastructures_inundation_duration=\u00dcberflutungsdauern Infrastrukturen BWaStr
+
+help.state.sinfo=${help.url}/OnlineHilfe/SINFO
+help.state.sinfo.river=${help.url}/OnlineHilfe/SINFO#help.state.sinfo.river
+help.state.sinfo.calculation_mode=${help.url}/OnlineHilfe/SINFO#help.state.sinfo.calculation_mode
+
+state.sinfo.distance_only = Range selection
+help.state.sinfo.distance_only=${help.url}/OnlineHilfe/SINFO#help.state.sinfo.distance_only
+
+state.sinfo.waterlevel_soundings_select= Chosen Differences
+help.state.sinfo.waterlevel_soundings_select=${help.url}/OnlineHilfe/SINFO#help.state.sinfo.waterlevel_soundings_select
+
+state.sinfo.use_transport_bodies=Transportk\u00f6rperh\u00f6hen
+help.state.sinfo.use_transport_bodies=${help.url}/OnlineHilfe/SINFO#help.state.sinfo.use_transport_bodies
+
+useTransportBodies.option = Transportk\u00f6rperh\u00f6hen miteinbeziehen?
+useTransportBodies.active = Activ
+useTransportBodies.inactive = Inactiv
+
+sinfo.export.flow_depth.csv.meta.header.result = ## Calculation Output - {0} - Flie\u00dftiefe - FLYS 3
+sinfo.export.flow_depth.csv.meta.version = # FLYS-Version: {0}
+sinfo.export.flow_depth.csv.meta.user = # Bearbeiter: {0}
+sinfo.export.flow_depth.csv.meta.creation = # Time of creation: {0}
+sinfo.export.flow_depth.csv.meta.river = # River: {0}
+sinfo.export.flow_depth.csv.meta.header.sounding = ##METADATEN PEILUNG
+sinfo.export.flow_depth.csv.meta.header.waterlevel = ##METADATEN WASSERSPIEGELLAGE
+
+#export.export.flow_depth.csv.meta.range = # Location/Range (km): {0} - {1}
+#export.export.flow_depth.csv.meta.gauge = # Gauge: {0}
+#export.export.flow_depth.csv.meta.q = # Q (m\u00b3/s): {0}
+#export.export.flow_depth.csv.meta.w = # W (NN + m): {0} - {1}
+
+sinfo.export.flow_depth.csv.header.km = Fluss-km
+sinfo.export.flow_depth.csv.header.flowdepth = Flie\u00dftiefe [m]
+sinfo.export.flow_depth.csv.header.flowdepthTkh = Flie\u00dftiefe mit TKH [m]
+sinfo.export.flow_depth.csv.header.tkh = Flie\u00dftiefe mit TKH [cm]
+# FIXME: H\u00f6henbezugssystem?
+sinfo.export.flow_depth.csv.header.waterlevel = Wasserstand [NN+m]
+sinfo.export.flow_depth.csv.header.discharge = Q [m\u00b3/s]
+sinfo.export.flow_depth.csv.header.label = Bezeichnung
+sinfo.export.flow_depth.csv.header.gauge = Bezugspegel
+# FIXME: H\u00f6henbezugssystem?
+sinfo.export.flow_depth.csv.header.mean_bed_height = Mittlere Sohlh\u00f6he [NN+m]
+sinfo.export.flow_depth.csv.header.sounding = Peilung/Epoche
+sinfo.export.flow_depth.csv.header.location = Lage
+
+sinfo.chart.flow_depth.section.title=h-L\u00e4ngsschnitt
+
+sinfo.chart.flow_depth.xaxis.label = {0}-km
+sinfo.chart.flow_depth.yaxis.label = Flie\u00dftiefe [m]
+
+sinfo.chart.flow_depth.section.yaxis.label=Flie\u00dftiefe h [m]
+sinfo.facet.flow_depth.filtered.description = Flie\u00dftiefe ({0})
diff -r 0862ea5d66ba -r 28df64078f27 artifacts/src/main/resources/messages_de.properties
--- a/artifacts/src/main/resources/messages_de.properties Thu Jan 18 20:54:03 2018 +0100
+++ b/artifacts/src/main/resources/messages_de.properties Fri Jan 19 11:23:42 2018 +0100
@@ -36,10 +36,10 @@
state.fix.analysis.referenceperiod = Bezugszeitraum
state.fix.analysis.analysisperiods = Analysezeitr\u00e4ume
state.fix.analysis.function = Ausgleichsfunktion
-state.fix.analysis.preprocessing = Ausrei\u00DFer
+state.fix.analysis.preprocessing = Ausrei\u00dfer
state.fix.preprocess=Ausrei\u00dfertest durchf\u00fchren
state.fix.vollmer.function= Ausgleichsfunktion
-state.fix.vollmer.preprocessing = Ausrei\u00DFer
+state.fix.vollmer.preprocessing = Ausrei\u00dfer
state.fix.vollmer.qs = Eingabe f\u00fcr W/Q Daten
state.minfo.river = Gew\u00e4sser
@@ -286,7 +286,7 @@
facet.sedimentload.calc.bed_load = Geschiebefracht (Berechnung FLYS) - {0} [{1}]
facet.sedimentload.calc.bed_load_susp_sand = bettbildende Fracht (Berechnung FLYS) - {0} [{1}]
-minfo.sedimentload.no.data = Keine Sedimentfracht-Daten verfügbar
+minfo.sedimentload.no.data = Keine Sedimentfracht-Daten verf\u00fcgbar
sedimentload.missing.fraction.coarse = Fehlende Fraktion Grober Kies/Steine - {0}
sedimentload.missing.fraction.fine_middle = Fehlende Fraktion Fein/Mittlerer Kies - {0}
sedimentload.missing.fraction.sand = Fehlende Fraktion Sand - {0}
@@ -730,6 +730,7 @@
static.sq.station = Messstelle
module.winfo = W-INFO
+module.sinfo = S-INFO
module.minfo = M-INFO
module.fixanalysis = Fixierungsanalyse
module.new_map = Neue Karte
@@ -766,3 +767,65 @@
help.state.fix.vollmer.preprocessing=${help.url}/OnlineHilfe/Fixierungsanalyse#help.state.fix.vollmer.preprocessing
help.state.fix.vollmer.qs=${help.url}/OnlineHilfe/Fixierungsanalyse#help.state.fix.vollmer.qs
help.state.fix.vollmer.compute=${help.url}/OnlineHilfe/Fixierungsanalyse#help.state.fix.vollmer.compute
+
+state.sinfo.river = Gew\u00e4sser
+state.sinfo.calculation_mode=Berechnungsart
+
+sinfo_calc_flow_depth=Flie\u00dftiefen
+sinfo_calc_flow_depth_development=Flie\u00dftiefenentwicklung
+sinfo_calc_flow_depth_minmax=Minimale und Maximale Flie\u00dftiefe
+sinfo_calc_grounding=Grundber\u00fchrungen
+sinfo_calc_transport_bodies_heights=Transportk\u00f6rperh\u00f6hen
+sinfo_calc_infrastructures_inundation_duration=\u00dcberflutungsdauern Infrastrukturen BWaStr
+
+help.state.sinfo=${help.url}/OnlineHilfe/SINFO
+help.state.sinfo.river=${help.url}/OnlineHilfe/SINFO#help.state.sinfo.river
+help.state.sinfo.calculation_mode=${help.url}/OnlineHilfe/SINFO#help.state.sinfo.calculation_mode
+
+state.sinfo.distance_only = Wahl der Berechnungsstrecke
+help.state.sinfo.distance_only=${help.url}/OnlineHilfe/SINFO#help.state.sinfo.distance_only
+
+state.sinfo.waterlevel_soundings_select= Ausgew\u00e4hlte Differenzen
+help.state.sinfo.waterlevel_soundings_select=${help.url}/OnlineHilfe/SINFO#help.state.sinfo.waterlevel_soundings_select
+
+state.sinfo.use_transport_bodies=Transportk\u00f6rperh\u00f6hen
+help.state.sinfo.use_transport_bodies=${help.url}/OnlineHilfe/SINFO#help.state.sinfo.use_transport_bodies
+
+useTransportBodies.option = Transportk\u00f6rperh\u00f6hen miteinbeziehen?
+useTransportBodies.active = Aktiv
+useTransportBodies.inactive = Inaktiv
+
+sinfo.export.flow_depth.csv.meta.header.result = ## Ergebnisausgabe - {0} - Flie\u00dftiefe - FLYS 3
+sinfo.export.flow_depth.csv.meta.version = # FLYS-Version: {0}
+sinfo.export.flow_depth.csv.meta.user = # Bearbeiter: {0}
+sinfo.export.flow_depth.csv.meta.creation = # Datum der Erstellung: {0}
+sinfo.export.flow_depth.csv.meta.river = # Gew\u00e4sser: {0}
+sinfo.export.flow_depth.csv.meta.header.sounding = ##METADATEN PEILUNG
+sinfo.export.flow_depth.csv.meta.header.waterlevel = ##METADATEN WASSERSPIEGELLAGE
+
+#export.export.flow_depth.csv.meta.range = # Location/Range (km): {0} - {1}
+#export.export.flow_depth.csv.meta.gauge = # Gauge: {0}
+#export.export.flow_depth.csv.meta.q = # Q (m\u00b3/s): {0}
+#export.export.flow_depth.csv.meta.w = # W (NN + m): {0} - {1}
+
+sinfo.export.flow_depth.csv.header.km = Fluss-km
+sinfo.export.flow_depth.csv.header.flowdepth = Flie\u00dftiefe [m]
+sinfo.export.flow_depth.csv.header.flowdepthTkh = Flie\u00dftiefe mit TKH [m]
+sinfo.export.flow_depth.csv.header.tkh = Flie\u00dftiefe mit TKH [cm]
+# FIXME: H\u00f6henbezugssystem?
+sinfo.export.flow_depth.csv.header.waterlevel = Wasserstand [NN+m]
+sinfo.export.flow_depth.csv.header.discharge = Q [m\u00b3/s]
+sinfo.export.flow_depth.csv.header.label = Bezeichnung
+sinfo.export.flow_depth.csv.header.gauge = Bezugspegel
+# FIXME: H\u00f6henbezugssystem?
+sinfo.export.flow_depth.csv.header.mean_bed_height = Mittlere Sohlh\u00f6he [NN+m]
+sinfo.export.flow_depth.csv.header.sounding = Peilung/Epoche
+sinfo.export.flow_depth.csv.header.location = Lage
+
+sinfo.chart.flow_depth.section.title=h-L\u00e4ngsschnitt
+
+sinfo.chart.flow_depth.xaxis.label = {0}-km
+sinfo.chart.flow_depth.yaxis.label = Flie\u00dftiefe [m]
+
+sinfo.chart.flow_depth.section.yaxis.label=Flow Depth h [m]
+sinfo.facet.flow_depth.filtered.description = Flie\u00dftiefe ({0})
\ No newline at end of file
diff -r 0862ea5d66ba -r 28df64078f27 artifacts/src/main/resources/messages_de_DE.properties
--- a/artifacts/src/main/resources/messages_de_DE.properties Thu Jan 18 20:54:03 2018 +0100
+++ b/artifacts/src/main/resources/messages_de_DE.properties Fri Jan 19 11:23:42 2018 +0100
@@ -36,10 +36,10 @@
state.fix.analysis.referenceperiod = Bezugszeitraum
state.fix.analysis.analysisperiods = Analysezeitr\u00e4ume
state.fix.analysis.function = Ausgleichsfunktion
-state.fix.analysis.preprocessing = Ausrei\u00DFer
+state.fix.analysis.preprocessing = Ausrei\u00dfer
state.fix.preprocess=Ausrei\u00dfertest durchf\u00fchren
state.fix.vollmer.function= Ausgleichsfunktion
-state.fix.vollmer.preprocessing = Ausrei\u00DFer
+state.fix.vollmer.preprocessing = Ausrei\u00dfer
state.fix.vollmer.qs = Eingabe f\u00fcr W/Q Daten
state.minfo.river = Gew\u00e4sser
@@ -283,7 +283,7 @@
facet.sedimentload.calc.bed_load = Geschiebefracht (Berechnung FLYS) - {0} [{1}]
facet.sedimentload.calc.bed_load_susp_sand = bettbildende Fracht (Berechnung FLYS) - {0} [{1}]
-minfo.sedimentload.no.data = Keine Sedimentfracht-Daten verfügbar
+minfo.sedimentload.no.data = Keine Sedimentfracht-Daten verf\u00fcgbar
sedimentload.missing.fraction.coarse = Fehlende Fraktion Grober Kies/Steine - {0}
sedimentload.missing.fraction.fine_middle = Fehlende Fraktion Fein/Mittlerer Kies - {0}
sedimentload.missing.fraction.sand = Fehlende Fraktion Sand - {0}
@@ -763,3 +763,65 @@
help.state.fix.vollmer.preprocessing=${help.url}/OnlineHilfe/Fixierungsanalyse#help.state.fix.vollmer.preprocessing
help.state.fix.vollmer.qs=${help.url}/OnlineHilfe/Fixierungsanalyse#help.state.fix.vollmer.qs
help.state.fix.vollmer.compute=${help.url}/OnlineHilfe/Fixierungsanalyse#help.state.fix.vollmer.compute
+
+state.sinfo.river = Gew\u00e4sser
+state.sinfo.calculation_mode=Berechnungsart
+
+sinfo_calc_flow_depth=Flie\u00dftiefen
+sinfo_calc_flow_depth_development=Flie\u00dftiefenentwicklung
+sinfo_calc_flow_depth_minmax=Minimale und Maximale Flie\u00dftiefe
+sinfo_calc_grounding=Grundber\u00fchrungen
+sinfo_calc_transport_bodies_heights=Transportk\u00f6rperh\u00f6hen
+sinfo_calc_infrastructures_inundation_duration=\u00dcberflutungsdauern Infrastrukturen BWaStr
+
+help.state.sinfo=${help.url}/OnlineHilfe/SINFO
+help.state.sinfo.river=${help.url}/OnlineHilfe/SINFO#help.state.sinfo.river
+help.state.sinfo.calculation_mode=${help.url}/OnlineHilfe/SINFO#help.state.sinfo.calculation_mode
+
+state.sinfo.distance_only = Wahl der Berechnungsstrecke
+help.state.sinfo.distance_only=${help.url}/OnlineHilfe/SINFO#help.state.sinfo.distance_only
+
+state.sinfo.waterlevel_soundings_select= Ausgew\u00e4hlte Differenzen
+help.state.sinfo.waterlevel_soundings_select=${help.url}/OnlineHilfe/SINFO#help.state.sinfo.waterlevel_soundings_select
+
+state.sinfo.use_transport_bodies=Transportk\u00f6rperh\u00f6hen
+help.state.sinfo.use_transport_bodies=${help.url}/OnlineHilfe/SINFO#help.state.sinfo.use_transport_bodies
+
+useTransportBodies.option = Transportk\u00f6rperh\u00f6hen miteinbeziehen?
+useTransportBodies.active = Aktiv
+useTransportBodies.inactive = Inaktiv
+
+sinfo.export.flow_depth.csv.meta.header.result = ## Ergebnisausgabe - {0} - Flie\u00dftiefe - FLYS 3
+sinfo.export.flow_depth.csv.meta.version = # FLYS-Version: {0}
+sinfo.export.flow_depth.csv.meta.user = # Bearbeiter: {0}
+sinfo.export.flow_depth.csv.meta.creation = # Datum der Erstellung: {0}
+sinfo.export.flow_depth.csv.meta.river = # Gew\u00e4sser: {0}
+sinfo.export.flow_depth.csv.meta.header.sounding = ##METADATEN PEILUNG
+sinfo.export.flow_depth.csv.meta.header.waterlevel = ##METADATEN WASSERSPIEGELLAGE
+
+#export.export.flow_depth.csv.meta.range = # Location/Range (km): {0} - {1}
+#export.export.flow_depth.csv.meta.gauge = # Gauge: {0}
+#export.export.flow_depth.csv.meta.q = # Q (m\u00b3/s): {0}
+#export.export.flow_depth.csv.meta.w = # W (NN + m): {0} - {1}
+
+sinfo.export.flow_depth.csv.header.km = Fluss-km
+sinfo.export.flow_depth.csv.header.flowdepth = Flie\u00dftiefe [m]
+sinfo.export.flow_depth.csv.header.flowdepthTkh = Flie\u00dftiefe mit TKH [m]
+sinfo.export.flow_depth.csv.header.tkh = Flie\u00dftiefe mit TKH [cm]
+# FIXME: H\u00f6henbezugssystem?
+sinfo.export.flow_depth.csv.header.waterlevel = Wasserstand [NN+m]
+sinfo.export.flow_depth.csv.header.discharge = Q [m\u00b3/s]
+sinfo.export.flow_depth.csv.header.label = Bezeichnung
+sinfo.export.flow_depth.csv.header.gauge = Bezugspegel
+# FIXME: H\u00f6henbezugssystem?
+sinfo.export.flow_depth.csv.header.mean_bed_height = Mittlere Sohlh\u00f6he [NN+m]
+sinfo.export.flow_depth.csv.header.sounding = Peilung/Epoche
+sinfo.export.flow_depth.csv.header.location = Lage
+
+sinfo.chart.flow_depth.section.title=h-L\u00e4ngsschnitt
+
+sinfo.chart.flow_depth.xaxis.label = {0}-km
+sinfo.chart.flow_depth.yaxis.label = Flie\u00dftiefe [m]
+
+sinfo.chart.flow_depth.section.yaxis.label=Flow Depth h [m]
+sinfo.facet.flow_depth.filtered.description = Flie\u00dftiefe ({0})
\ No newline at end of file
diff -r 0862ea5d66ba -r 28df64078f27 artifacts/src/main/resources/messages_en.properties
--- a/artifacts/src/main/resources/messages_en.properties Thu Jan 18 20:54:03 2018 +0100
+++ b/artifacts/src/main/resources/messages_en.properties Fri Jan 19 11:23:42 2018 +0100
@@ -762,3 +762,65 @@
help.state.fix.vollmer.preprocessing=${help.url}/OnlineHilfe/Fixierungsanalyse#help.state.fix.vollmer.preprocessing
help.state.fix.vollmer.qs=${help.url}/OnlineHilfe/Fixierungsanalyse#help.state.fix.vollmer.qs
help.state.fix.vollmer.compute=${help.url}/OnlineHilfe/Fixierungsanalyse#help.state.fix.vollmer.compute
+
+state.sinfo.river = River
+state.sinfo.calculation_mode=Calculation Mode
+
+sinfo_calc_flow_depth=Flie\u00dftiefen
+sinfo_calc_flow_depth_development=Flie\u00dftiefenentwicklung
+sinfo_calc_flow_depth_minmax=Minimale und Maximale Flie\u00dftiefe
+sinfo_calc_grounding=Grundber\u00fchrungen
+sinfo_calc_transport_bodies_heights=Transportk\u00f6rperh\u00f6hen
+sinfo_calc_infrastructures_inundation_duration=\u00dcberflutungsdauern Infrastrukturen BWaStr
+
+help.state.sinfo=${help.url}/OnlineHilfe/SINFO
+help.state.sinfo.river=${help.url}/OnlineHilfe/SINFO#help.state.sinfo.river
+help.state.sinfo.calculation_mode=${help.url}/OnlineHilfe/SINFO#help.state.sinfo.calculation_mode
+
+state.sinfo.distance_only = Range selection
+help.state.sinfo.distance_only=${help.url}/OnlineHilfe/SINFO#help.state.sinfo.distance_only
+
+state.sinfo.waterlevel_soundings_select= Chosen Differences
+help.state.sinfo.waterlevel_soundings_select=${help.url}/OnlineHilfe/SINFO#help.state.sinfo.waterlevel_soundings_select
+
+state.sinfo.use_transport_bodies=Transportk\u00f6rperh\u00f6hen
+help.state.sinfo.use_transport_bodies=${help.url}/OnlineHilfe/SINFO#help.state.sinfo.use_transport_bodies
+
+useTransportBodies.option = Transportk\u00f6rperh\u00f6hen miteinbeziehen?
+useTransportBodies.active = Activ
+useTransportBodies.inactive = Inactiv
+
+sinfo.export.flow_depth.csv.meta.header.result = ## Calculation Output - {0} - Flie\u00dftiefe - FLYS 3
+sinfo.export.flow_depth.csv.meta.version = # FLYS-Version: {0}
+sinfo.export.flow_depth.csv.meta.user = # Bearbeiter: {0}
+sinfo.export.flow_depth.csv.meta.creation = # Time of creation: {0}
+sinfo.export.flow_depth.csv.meta.river = # River: {0}
+sinfo.export.flow_depth.csv.meta.header.sounding = ##METADATEN PEILUNG
+sinfo.export.flow_depth.csv.meta.header.waterlevel = ##METADATEN WASSERSPIEGELLAGE
+
+#export.export.flow_depth.csv.meta.range = # Location/Range (km): {0} - {1}
+#export.export.flow_depth.csv.meta.gauge = # Gauge: {0}
+#export.export.flow_depth.csv.meta.q = # Q (m\u00b3/s): {0}
+#export.export.flow_depth.csv.meta.w = # W (NN + m): {0} - {1}
+
+sinfo.export.flow_depth.csv.header.km = Fluss-km
+sinfo.export.flow_depth.csv.header.flowdepth = Flie\u00dftiefe [m]
+sinfo.export.flow_depth.csv.header.flowdepthTkh = Flie\u00dftiefe mit TKH [m]
+sinfo.export.flow_depth.csv.header.tkh = Flie\u00dftiefe mit TKH [cm]
+# FIXME: H\u00f6henbezugssystem?
+sinfo.export.flow_depth.csv.header.waterlevel = Wasserstand [NN+m]
+sinfo.export.flow_depth.csv.header.discharge = Q [m\u00b3/s]
+sinfo.export.flow_depth.csv.header.label = Bezeichnung
+sinfo.export.flow_depth.csv.header.gauge = Bezugspegel
+# FIXME: H\u00f6henbezugssystem?
+sinfo.export.flow_depth.csv.header.mean_bed_height = Mittlere Sohlh\u00f6he [NN+m]
+sinfo.export.flow_depth.csv.header.sounding = Peilung/Epoche
+sinfo.export.flow_depth.csv.header.location = Lage
+
+sinfo.chart.flow_depth.section.title=h-L\u00e4ngsschnitt
+
+sinfo.chart.flow_depth.xaxis.label = {0}-km
+sinfo.chart.flow_depth.yaxis.label = Flie\u00dftiefe [m]
+
+sinfo.chart.flow_depth.section.yaxis.label=Flie\u00dftiefe h [m]
+sinfo.facet.flow_depth.filtered.description = Flie\u00dftiefe ({0})
\ No newline at end of file
diff -r 0862ea5d66ba -r 28df64078f27 gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.java
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.java Thu Jan 18 20:54:03 2018 +0100
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.java Fri Jan 19 11:23:42 2018 +0100
@@ -1421,5 +1421,15 @@
String error_no_sedimentloadinfo_found();
String error_no_sedimentloadinfo_data();
+
+ String sinfo();
+
+ String sinfo_flowdepth_export();
+
+ String sinfo_flowdepth_report();
+
+ String sinfo_flow_depth();
+
+ String sinfo_flowdepth_twinpanel_no_pair_selected();
}
-// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
\ No newline at end of file
diff -r 0862ea5d66ba -r 28df64078f27 gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.properties
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.properties Thu Jan 18 20:54:03 2018 +0100
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.properties Fri Jan 19 11:23:42 2018 +0100
@@ -756,3 +756,9 @@
upper_time = to
no_data_for_year = No data available for: $1
+
+sinfo = S-INFO
+sinfo_flowdepth_export = Flie\u00dftiefen Export
+sinfo_flowdepth_report = Flie\u00dftiefen Bericht
+sinfo_flow_depth = Flie\u00dftiefen
+sinfo_flowdepth_twinpanel_no_pair_selected = Error - at least one input pair must be selected
\ No newline at end of file
diff -r 0862ea5d66ba -r 28df64078f27 gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants_de.properties
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants_de.properties Thu Jan 18 20:54:03 2018 +0100
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants_de.properties Fri Jan 19 11:23:42 2018 +0100
@@ -748,3 +748,9 @@
upper_time = bis
no_data_for_year = F\u00fcr das Jahr $1 liegen keine Daten vor.
+
+sinfo = S-INFO
+sinfo_flowdepth_export = Flie\u00dftiefen Export
+sinfo_flowdepth_report = Flie\u00dftiefen Bericht
+sinfo_flow_depth = Flie\u00dftiefen
+sinfo_flowdepth_twinpanel_no_pair_selected = Fehler - kein Paar zur Differenzenbildung gew\u00e4hlt.
\ No newline at end of file
diff -r 0862ea5d66ba -r 28df64078f27 gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants_en.properties
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants_en.properties Thu Jan 18 20:54:03 2018 +0100
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants_en.properties Fri Jan 19 11:23:42 2018 +0100
@@ -785,3 +785,9 @@
upper_time = to
no_data_for_year = No data available for: $1
+
+sinfo = S-INFO
+sinfo_flowdepth_export = Flie\u00dftiefen Export
+sinfo_flowdepth_report = Flie\u00dftiefen Bericht
+sinfo_flow_depth = Flie\u00dftiefen
+sinfo_flowdepth_twinpanel_no_pair_selected = Error - at least one input pair must be selected
\ No newline at end of file
diff -r 0862ea5d66ba -r 28df64078f27 gwt-client/src/main/java/org/dive4elements/river/client/client/ui/AbstractPairRecommendationPanel.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/AbstractPairRecommendationPanel.java Fri Jan 19 11:23:42 2018 +0100
@@ -0,0 +1,508 @@
+/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
+ * Software engineering by Intevation GmbH
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+
+package org.dive4elements.river.client.client.ui;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.rpc.AsyncCallback;
+
+import com.smartgwt.client.data.Record;
+import com.smartgwt.client.types.ListGridFieldType;
+import com.smartgwt.client.widgets.Canvas;
+import com.smartgwt.client.widgets.events.ClickEvent;
+import com.smartgwt.client.widgets.grid.ListGrid;
+import com.smartgwt.client.widgets.grid.ListGridField;
+import com.smartgwt.client.widgets.grid.ListGridRecord;
+import com.smartgwt.client.widgets.grid.events.RecordClickEvent;
+import com.smartgwt.client.widgets.grid.events.RecordClickHandler;
+import com.smartgwt.client.widgets.layout.VLayout;
+
+import org.dive4elements.river.client.client.Config;
+import org.dive4elements.river.client.client.FLYSConstants;
+import org.dive4elements.river.client.client.event.StepForwardEvent;
+import org.dive4elements.river.client.client.services.LoadArtifactServiceAsync;
+import org.dive4elements.river.client.client.services.RemoveArtifactServiceAsync;
+import org.dive4elements.river.client.shared.model.Artifact;
+import org.dive4elements.river.client.shared.model.Collection;
+import org.dive4elements.river.client.shared.model.Data;
+import org.dive4elements.river.client.shared.model.DataItem;
+import org.dive4elements.river.client.shared.model.DataList;
+import org.dive4elements.river.client.shared.model.DefaultData;
+import org.dive4elements.river.client.shared.model.DefaultDataItem;
+import org.dive4elements.river.client.shared.model.Recommendation;
+import org.dive4elements.river.client.shared.model.Recommendation.Facet;
+import org.dive4elements.river.client.shared.model.Recommendation.Filter;
+import org.dive4elements.river.client.shared.model.User;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+// TODO Probably better to branch off AbstractUIProvider.
+// TODO Merge with other datacage-widget impls.
+/**
+ * Panel containing a Grid and a "next" button. The Grid is fed by a
+ * DatacagePairWidget which is put in the input-helper area.
+ */
+public abstract class AbstractPairRecommendationPanel
+extends TextProvider {
+
+ /**
+ * Allows for abstraction on how to handle/serialize the recommendation and the used factories.
+ * @author Gernot Belger
+ *
+ */
+ public static interface IRecommendationInfo {
+
+ String getFactory();
+
+ /**
+ * Separate factory for the 'createDataString' method, because in the case of waterlevels. See HOTFIX/FIXME there.
+ */
+ String getDataStringFactory();
+
+ /**
+ * Set factory of recommendation such that the correct artifacts will
+ * be cloned for difference calculations.
+ */
+ void adjustRecommendation(Recommendation recommendation);
+ }
+
+ public static interface IValidator
+ {
+ List validate(ListGrid differencesList, FLYSConstants msgProvider);
+ }
+
+ private static final long serialVersionUID = 8906629596491827857L;
+
+ // FIXME: why? we hide the field of the super class with exactly the same thing...
+ private static FLYSConstants MSG_PROVIDER = GWT.create(FLYSConstants.class);
+
+ private String dataName;
+
+ private User user;
+
+ /** ListGrid that displays user-selected pairs to build differences with. */
+ private ListGrid differencesList;
+
+ /**
+ * List to track previously selected but now removed pairs. (Needed to
+ * be able to identify artifacts that can be removed from the collection.
+ */
+ private List removedPairs =
+ new ArrayList();
+
+ /** Service handle to clone and add artifacts to collection. */
+ private LoadArtifactServiceAsync loadArtifactService = GWT.create(
+ org.dive4elements.river.client.client.services.LoadArtifactService.class);
+
+ /** Service to remove artifacts from collection. */
+ private RemoveArtifactServiceAsync removeArtifactService = GWT.create(
+ org.dive4elements.river.client.client.services.RemoveArtifactService.class);
+
+ private IRecommendationInfo leftInfo;
+
+ private IRecommendationInfo rightInfo;
+
+ private IValidator validator;
+
+ /**
+ * @param Validates the content of this form when the user clicks 'apply'
+ * @param leftInfo Delegate for handling the left part of the recommendation-pair
+ * @param rightInfo Delegate for handling the right part of the recommendation-pair
+ */
+ public AbstractPairRecommendationPanel(final User user, IValidator validator, final IRecommendationInfo leftInfo, final IRecommendationInfo rightInfo ) {
+ this.user = user;
+ this.validator = validator;
+ this.leftInfo = leftInfo;
+ this.rightInfo = rightInfo;
+ }
+
+ // FIXME: better than copy/pasting the MSG field into every sub-class but not really nice yet.
+ protected final static FLYSConstants msg() {
+ return MSG_PROVIDER;
+ }
+
+ /**
+ * Remove first occurrence of "[" and "]" (if both do occur).
+ * @param value String to be stripped of [] (might be null).
+ * @return input string but with [ and ] removed, or input string if no
+ * brackets were found.
+ * @see StringUtil.unbracket
+ */
+ // FIXME: check if this is the same as STringUItils#unbracket
+ private static final String unbracket(String value) {
+ // null- guard.
+ if (value == null) return value;
+
+ int start = value.indexOf("[");
+ int end = value.indexOf("]");
+
+ if (start < 0 || end < 0) {
+ return value;
+ }
+
+ return value.substring(start + 1, end);
+ }
+
+ /**
+ * Create a recommendation from a string representation of it.
+ * @param from string in format as shown above.
+ * @param leftInfo2
+ * @return recommendation from input string.
+ */
+ private Recommendation createRecommendationFromString(final String from, final IRecommendationInfo info) {
+ // TODO Construct "real" filter.
+ String[] parts = unbracket(from).split(";");
+ Recommendation.Filter filter = new Recommendation.Filter();
+ Recommendation.Facet facet = new Recommendation.Facet(
+ parts[1],
+ parts[2]);
+
+ List facets = new ArrayList();
+ facets.add(facet);
+ filter.add("longitudinal_section", facets);
+
+ final String factory = info.getFactory( );
+
+ final Recommendation r = new Recommendation(factory, parts[0], this.artifact.getUuid(), filter);
+ r.setDisplayName(parts[3]);
+ return r;
+ }
+
+
+ /**
+ * Add RecomendationPairRecords from input String to the ListGrid.
+ */
+ private void populateGridFromString(String from){
+ // Split this string.
+ // Create according recommendations and display strings.
+ String[] recs = from.split("#");
+ if (recs.length % 2 != 0) return;
+ for (int i = 0; i < recs.length; i+=2) {
+ Recommendation minuend =
+ createRecommendationFromString(recs[i+0], leftInfo);
+ Recommendation subtrahend =
+ createRecommendationFromString(recs[i+1], rightInfo);
+
+ RecommendationPairRecord pr = new RecommendationPairRecord(
+ minuend, subtrahend);
+ // This Recommendation Pair comes from the data string and was thus
+ // already cloned.
+ pr.setIsAlreadyLoaded(true);
+ this.differencesList.addData(pr);
+ }
+ }
+
+ /**
+ * Creates the graphical representation and interaction widgets for the data.
+ * @param dataList the data.
+ * @return graphical representation and interaction widgets for data.
+ */
+ @Override
+ public final Canvas create(DataList dataList) {
+
+ final Canvas widget = createWidget();
+
+ final Canvas canvas = createChooserWidgets(widget, dataList, user, differencesList);
+
+ populateGrid(dataList);
+
+ return canvas;
+ }
+
+ /**
+ * Creates the individual parts of the input-helper area ('Eingabeunterstützung') for choosing the content of this widget.
+ */
+ protected abstract Canvas createChooserWidgets(final Canvas widget, final DataList dataList, final User auser, final ListGrid diffList);
+
+ private void populateGrid(DataList dataList) {
+ Data data = dataList.get(0);
+ this.dataName = data.getLabel();
+ for (int i = 0; i < dataList.size(); i++) {
+ if (dataList.get(i) != null && dataList.get(i).getItems() != null) {
+ if (dataList.get(i).getItems() != null) {
+ populateGridFromString(
+ dataList.get(i).getItems()[0].getStringValue());
+ }
+ }
+ }
+ }
+
+ @Override
+ public final List validate() {
+ return validator.validate(differencesList, MSG_PROVIDER);
+ }
+
+ /**
+ * Creates layout with grid that displays selection inside.
+ */
+ protected final Canvas createWidget() {
+ VLayout layout = new VLayout();
+ differencesList = new ListGrid();
+
+ differencesList.setCanEdit(false);
+ differencesList.setCanSort(false);
+ differencesList.setShowHeaderContextMenu(false);
+ differencesList.setHeight(150);
+ differencesList.setShowAllRecords(true);
+
+ ListGridField nameField = new ListGridField("first", "Minuend");
+ ListGridField capitalField = new ListGridField("second", "Subtrahend");
+ // Track removed rows, therefore more or less reimplement
+ // setCanRecomeRecords.
+ final ListGridField removeField =
+ new ListGridField("_removeRecord", "Remove Record"){{
+ setType(ListGridFieldType.ICON);
+ setIcon(GWT.getHostPageBaseURL() + msg().removeFeature());
+ setCanEdit(false);
+ setCanFilter(false);
+ setCanSort(false);
+ setCanGroupBy(false);
+ setCanFreeze(false);
+ setWidth(25);
+ }};
+
+ differencesList.setFields(new ListGridField[] {nameField,
+ capitalField, removeField});
+
+ differencesList.addRecordClickHandler(new RecordClickHandler() {
+ @Override
+ public void onRecordClick(final RecordClickEvent event) {
+ // Just handle remove-clicks
+ if(!event.getField().getName().equals(removeField.getName())) {
+ return;
+ }
+ trackRemoved(event.getRecord());
+ event.getViewer().removeData(event.getRecord());
+ }
+ });
+ layout.addMember(differencesList);
+
+ return layout;
+ }
+
+
+ /**
+ * Add record to list of removed records.
+ */
+ protected final void trackRemoved(Record r) {
+ RecommendationPairRecord pr = (RecommendationPairRecord) r;
+ this.removedPairs.add(pr);
+ }
+
+ /**
+ * Validates data, does nothing if invalid, otherwise clones new selected
+ * waterlevels and add them to collection, forward the artifact.
+ */
+ @Override
+ public void onClick(ClickEvent e) {
+ GWT.log("AbstractPairRecommendationPanel.onClick");
+
+ List errors = validate();
+ if (errors != null && !errors.isEmpty()) {
+ showErrors(errors);
+ return;
+ }
+
+ Config config = Config.getInstance();
+ String locale = config.getLocale();
+
+ ListGridRecord[] records = differencesList.getRecords();
+
+ List ar = new ArrayList();
+ List all = new ArrayList();
+
+ for (ListGridRecord record : records) {
+ RecommendationPairRecord r =
+ (RecommendationPairRecord) record;
+ // Do not add "old" recommendations.
+ if (!r.isAlreadyLoaded()) {
+ // Check whether one of those is a dike or similar.
+ // TODO differentiate and merge: new clones, new, old.
+ Recommendation firstR = r.getFirst();
+ leftInfo.adjustRecommendation(firstR);
+
+ Recommendation secondR = r.getSecond();
+ rightInfo.adjustRecommendation(secondR);
+ ar.add(firstR);
+ ar.add(secondR);
+ }
+ else {
+ all.add(r.getFirst());
+ all.add(r.getSecond());
+ }
+ }
+
+ final Recommendation[] toClone = ar.toArray(new Recommendation[ar.size()]);
+ final Recommendation[] toUse = all.toArray(new Recommendation[all.size()]);
+
+ // Find out whether "old" artifacts have to be removed.
+ List artifactIdsToRemove = new ArrayList();
+ for (RecommendationPairRecord rp: this.removedPairs) {
+ Recommendation first = rp.getFirst();
+ Recommendation second = rp.getSecond();
+
+ for (Recommendation recommendation: toUse) {
+ if (first != null && first.getIDs().equals(recommendation.getIDs())) {
+ first = null;
+ }
+ if (second != null && second.getIDs().equals(recommendation.getIDs())) {
+ second = null;
+ }
+
+ if (first == null && second == null) {
+ break;
+ }
+ }
+ if (first != null) {
+ artifactIdsToRemove.add(first.getIDs());
+ }
+ if (second != null) {
+ artifactIdsToRemove.add(second.getIDs());
+ }
+ }
+
+ // Remove old artifacts, if any. Do this asychronously without much
+ // feedback.
+ for(final String uuid: artifactIdsToRemove) {
+ removeArtifactService.remove(this.collection,
+ uuid,
+ locale,
+ new AsyncCallback() {
+ @Override
+ public void onFailure(Throwable caught) {
+ GWT.log("RemoveArtifact (" + uuid + ") failed.");
+ }
+ @Override
+ public void onSuccess(Collection coll) {
+ GWT.log("RemoveArtifact succeeded");
+ }
+ });
+ }
+
+ // Clone new ones (and spawn statics), go forward.
+ parameterList.lockUI();
+ loadArtifactService.loadMany(
+ this.collection,
+ toClone,
+ //"staticwkms" and "waterlevel"
+ null,
+ locale,
+ new AsyncCallback() {
+ @Override
+ public void onFailure(Throwable caught) {
+ caught.printStackTrace();
+ GWT.log("Failure of cloning with factories!");
+ parameterList.unlockUI();
+ }
+ @Override
+ public void onSuccess(Artifact[] artifacts) {
+ GWT.log("Successfully cloned " + toClone.length +
+ " with factories.");
+
+ fireStepForwardEvent(new StepForwardEvent(
+ getData(toClone, artifacts, toUse)));
+ parameterList.unlockUI();
+ }
+ });
+ }
+
+ /**
+ * Create Data and DataItem from selection (a long string with identifiers
+ * to construct diff-pairs).
+ *
+ * @param newRecommendations "new" recommendations (did not survive a
+ * backjump).
+ * @param newArtifacts artifacts cloned from newRecommendations.
+ * @param oldRecommendations old recommendations that survived a backjump.
+ *
+ * @return dataitem with a long string with identifiers to construct
+ * diff-pairs.
+ */
+ protected final Data[] getData(
+ Recommendation[] newRecommendations,
+ Artifact[] newArtifacts,
+ Recommendation[] oldRecommendations)
+ {
+ // Construct string with info about selections.
+ String dataItemString = "";
+ for (int i = 0; i < newRecommendations.length; i++) {
+ Recommendation r = newRecommendations[i];
+ Artifact newArtifact = newArtifacts[i];
+ String uuid = newArtifact.getUuid();
+ r.setMasterArtifact(uuid);
+
+ if (i>0)
+ dataItemString += "#";
+
+ // REMARK: ugly, but we know that the recommandations comes in left/right pairs.
+ final IRecommendationInfo info = i % 2 == 0 ? leftInfo : rightInfo;
+
+ dataItemString += createDataString(uuid, r, info);
+ }
+
+ for (int i = 0; i < oldRecommendations.length; i++) {
+ Recommendation r = oldRecommendations[i];
+ String uuid = r.getIDs();
+
+ if (dataItemString.length() > 0)
+ dataItemString += "#";
+
+ // REMARK: ugly, but we know that the recommandations comes in left/right pairs.
+ final IRecommendationInfo info = i % 2 == 0 ? leftInfo : rightInfo;
+
+ dataItemString += createDataString(uuid, r, info);
+ }
+
+ // TODO some hassle could be resolved by using multiple DataItems
+ // (e.g. one per pair).
+ DataItem item = new DefaultDataItem(dataName, dataName, dataItemString);
+ return new Data[] { new DefaultData(
+ dataName, null, null, new DataItem[] {item}) };
+ }
+
+ /**
+ * Creates part of the String that encodes minuend or subtrahend.
+ * @param recommendation Recommendation to wrap in string.
+ * @param info Provides the factory to encode.
+ */
+ protected static final String createDataString(final String artifactUuid, final Recommendation recommendation, final IRecommendationInfo info) {
+ final String factory = info.getDataStringFactory();
+
+ Filter filter = recommendation.getFilter();
+ Facet f = null;
+
+ if(filter != null) {
+ Map> outs = filter.getOuts();
+ Set>> entries = outs.entrySet();
+
+ for (Map.Entry> entry: entries) {
+ List fs = entry.getValue();
+
+ f = fs.get(0);
+ if (f != null) {
+ break;
+ }
+ }
+
+ return "[" + artifactUuid + ";"
+ + f.getName()
+ + ";"
+ + f.getIndex()
+ + ";"
+ + recommendation.getDisplayName() + "]";
+ }
+
+ return "["
+ + artifactUuid
+ + ";" + factory + ";0;"
+ + recommendation.getDisplayName() + "]";
+ }
+}
\ No newline at end of file
diff -r 0862ea5d66ba -r 28df64078f27 gwt-client/src/main/java/org/dive4elements/river/client/client/ui/AbstractUIProvider.java
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/AbstractUIProvider.java Thu Jan 18 20:54:03 2018 +0100
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/AbstractUIProvider.java Fri Jan 19 11:23:42 2018 +0100
@@ -309,12 +309,14 @@
return null;
}
-
+ /**
+ * Validates the selection.
+ * @return List of internationalized errror messages (if any).
+ */
public List validate() {
return new ArrayList(); // FIXME: What's this?
}
-
/** Create simple DefaultData with single DataItem inside. */
public static DefaultData createDataArray(String name, String value) {
DataItem item = new DefaultDataItem(
diff -r 0862ea5d66ba -r 28df64078f27 gwt-client/src/main/java/org/dive4elements/river/client/client/ui/CollectionView.java
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/CollectionView.java Thu Jan 18 20:54:03 2018 +0100
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/CollectionView.java Fri Jan 19 11:23:42 2018 +0100
@@ -199,6 +199,9 @@
this.parameterList = new ParameterList(
flys,
this,
+ // FIXME: literally every information about the artifact is transported from the server side
+ // but... the international name is resolved client-side.... Instead also transport the description of the artifact and use it!
+ // FIXME: the same holds for a very few other international strings (e.g. names of facets used in Tabs)
messages.getString(artifact.getName()),
artifact);
}
diff -r 0862ea5d66ba -r 28df64078f27 gwt-client/src/main/java/org/dive4elements/river/client/client/ui/DatacagePairWidget.java
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/DatacagePairWidget.java Thu Jan 18 20:54:03 2018 +0100
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/DatacagePairWidget.java Fri Jan 19 11:23:42 2018 +0100
@@ -49,12 +49,14 @@
*
* @param artifact Artifact to query datacage with.
* @param user User to query datacage with.
- * @param outs outs to query datacage with.
+ * @param leftOuts outs to query the left datacage with.
+ * @param rightOuts outs to query the right datacage with.
* @param grid Grid into which to insert selection of pairs.
*/
public DatacagePairWidget(Artifact artifact,
User user,
- String outs,
+ String leftOuts,
+ String rightOuts,
ListGrid grid) {
this.grid = grid;
@@ -62,13 +64,13 @@
firstDatacageWidget = new DatacageWidget(
artifact,
user,
- outs,
+ leftOuts,
"load-system:true",
false);
secondDatacageWidget = new DatacageWidget(
artifact,
user,
- outs,
+ rightOuts,
"load-system:true",
false);
firstDatacageWidget.setIsMutliSelectable(false);
diff -r 0862ea5d66ba -r 28df64078f27 gwt-client/src/main/java/org/dive4elements/river/client/client/ui/DatacageTwinPanel.java
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/DatacageTwinPanel.java Thu Jan 18 20:54:03 2018 +0100
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/DatacageTwinPanel.java Fri Jan 19 11:23:42 2018 +0100
@@ -8,531 +8,56 @@
package org.dive4elements.river.client.client.ui;
+import org.dive4elements.river.client.shared.model.DataList;
+import org.dive4elements.river.client.shared.model.User;
+
import com.google.gwt.core.client.GWT;
-import com.google.gwt.user.client.rpc.AsyncCallback;
-
-import com.smartgwt.client.data.Record;
-import com.smartgwt.client.types.ListGridFieldType;
import com.smartgwt.client.widgets.Canvas;
-import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.grid.ListGrid;
-import com.smartgwt.client.widgets.grid.ListGridField;
-import com.smartgwt.client.widgets.grid.ListGridRecord;
-import com.smartgwt.client.widgets.grid.events.RecordClickEvent;
-import com.smartgwt.client.widgets.grid.events.RecordClickHandler;
import com.smartgwt.client.widgets.layout.HLayout;
import com.smartgwt.client.widgets.layout.VLayout;
-import org.dive4elements.river.client.client.Config;
-import org.dive4elements.river.client.client.FLYSConstants;
-import org.dive4elements.river.client.client.event.StepForwardEvent;
-import org.dive4elements.river.client.client.services.LoadArtifactServiceAsync;
-import org.dive4elements.river.client.client.services.RemoveArtifactServiceAsync;
-import org.dive4elements.river.client.shared.model.Artifact;
-import org.dive4elements.river.client.shared.model.Collection;
-import org.dive4elements.river.client.shared.model.Data;
-import org.dive4elements.river.client.shared.model.DataItem;
-import org.dive4elements.river.client.shared.model.DataList;
-import org.dive4elements.river.client.shared.model.DefaultData;
-import org.dive4elements.river.client.shared.model.DefaultDataItem;
-import org.dive4elements.river.client.shared.model.Recommendation;
-import org.dive4elements.river.client.shared.model.Recommendation.Facet;
-import org.dive4elements.river.client.shared.model.Recommendation.Filter;
-import org.dive4elements.river.client.shared.model.User;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-// TODO Probably better to branch off AbstractUIProvider.
-// TODO Merge with other datacage-widget impls.
/**
- * Panel containing a Grid and a "next" button. The Grid is fed by a
+ * A {@link AbstractPairRecommendationPanel} that uses a 'TwinDatacage' in the help-input area.
* DatacagePairWidget which is put in the input-helper area.
*/
-public class DatacageTwinPanel
-extends TextProvider {
-
- private static final long serialVersionUID = 8906629596491827857L;
-
- protected static FLYSConstants MSG = GWT.create(FLYSConstants.class);
-
- protected String dataName;
-
- protected User user;
-
- /** ListGrid that displays user-selected pairs to build differences with. */
- protected ListGrid differencesList;
-
- /**
- * List to track previously selected but now removed pairs. (Needed to
- * be able to identify artifacts that can be removed from the collection.
- */
- protected List removedPairs =
- new ArrayList();
-
- /** Service handle to clone and add artifacts to collection. */
- LoadArtifactServiceAsync loadArtifactService = GWT.create(
- org.dive4elements.river.client.client.services
- .LoadArtifactService.class);
-
- /** Service to remove artifacts from collection. */
- RemoveArtifactServiceAsync removeArtifactService = GWT.create(
- org.dive4elements.river.client.client.services
- .RemoveArtifactService.class);
-
-
- public DatacageTwinPanel(User user) {
- super();
- this.user = user;
- }
-
-
- /**
- * Remove first occurrence of "[" and "]" (if both do occur).
- * @param value String to be stripped of [] (might be null).
- * @return input string but with [ and ] removed, or input string if no
- * brackets were found.
- * @see StringUtil.unbracket
- */
- public static final String unbracket(String value) {
- // null- guard.
- if (value == null) return value;
-
- int start = value.indexOf("[");
- int end = value.indexOf("]");
-
- if (start < 0 || end < 0) {
- return value;
- }
-
- value = value.substring(start + 1, end);
+public abstract class DatacageTwinPanel
+extends AbstractPairRecommendationPanel {
- return value;
- }
-
-
- /**
- * Create a recommendation from a string representation of it.
- * @param from string in format as shown above.
- * @return recommendation from input string.
- */
- public Recommendation createRecommendationFromString(
- String from,
- String factory
- ) {
- // TODO Construct "real" filter.
- String[] parts = unbracket(from).split(";");
- Recommendation.Filter filter = new Recommendation.Filter();
- Recommendation.Facet facet = new Recommendation.Facet(
- parts[1],
- parts[2]);
-
- List facets = new ArrayList
- ();
- facets.add(facet);
- filter.add("longitudinal_section", facets);
- Recommendation r = new Recommendation(factory, parts[0],
- this.artifact.getUuid(), filter);
- r.setDisplayName(parts[3]);
- return r;
- }
-
+ private IDatacageTwinPanelInfo leftInfo;
+ private IDatacageTwinPanelInfo rightInfo;
- /**
- * Add RecomendationPairRecords from input String to the ListGrid.
- */
- public void populateGridFromString(String from, String factory){
- // Split this string.
- // Create according recommendations and display strings.
- String[] recs = from.split("#");
- if (recs.length % 2 != 0) return;
- for (int i = 0; i < recs.length; i+=2) {
- Recommendation minuend =
- createRecommendationFromString(recs[i+0], factory);
- Recommendation subtrahend =
- createRecommendationFromString(recs[i+1], factory);
+ public static interface IDatacageTwinPanelInfo extends IRecommendationInfo
+ {
+ String getOuts();
+ }
+
+ public DatacageTwinPanel(final User user, IValidator validator, final IDatacageTwinPanelInfo leftInfo, final IDatacageTwinPanelInfo rightInfo ) {
+ super(user, validator, leftInfo, rightInfo);
- RecommendationPairRecord pr = new RecommendationPairRecord(
- minuend, subtrahend);
- // This Recommendation Pair comes from the data string and was thus
- // already cloned.
- pr.setIsAlreadyLoaded(true);
- this.differencesList.addData(pr);
- }
- }
-
-
- /**
- * Creates the graphical representation and interaction widgets
- * for the data.
- * @param dataList the data.
- * @return graphical representation and interaction widgets for data.
- */
+ this.leftInfo = leftInfo;
+ this.rightInfo = rightInfo;
+ }
+
@Override
- public Canvas create(DataList dataList) {
+ protected final Canvas createChooserWidgets(final Canvas widget, final DataList dataList, final User user, final ListGrid differencesList) {
GWT.log("createData()");
- Canvas widget = createWidget();
Canvas submit = getNextButton();
VLayout layout = new VLayout();
HLayout helperLayout = new HLayout();
- helperLayout.addMember(new DatacagePairWidget(this.artifact,
- user, "winfo_diff_twin_panel", differencesList));
+
+ final String leftOuts = leftInfo.getOuts();
+ final String rightOuts = rightInfo.getOuts();
+
+ helperLayout.addMember(new DatacagePairWidget(this.artifact, user, leftOuts, rightOuts, differencesList));
layout.addMember(widget);
layout.addMember(submit);
layout.setMembersMargin(10);
this.helperContainer.addMember(helperLayout);
- populateGrid(dataList, "waterlevel");
- return layout;
- }
-
- protected void populateGrid(DataList dataList, String factory) {
- Data data = dataList.get(0);
- this.dataName = data.getLabel();
- for (int i = 0; i < dataList.size(); i++) {
- if (dataList.get(i) != null
- && dataList.get(i).getItems() != null
- ) {
- if (dataList.get(i).getItems() != null) {
- populateGridFromString(
- dataList.get(i).getItems()[0].getStringValue(),
- factory);
- }
- }
- }
- }
-
-
- /**
- * Validates the selection.
- * @return List of internationalized errror messages (if any).
- */
- @Override
- public List validate() {
- List errors = new ArrayList();
- if (differencesList.getRecords().length == 0) {
- errors.add(MSG.error_no_waterlevel_pair_selected());
- }
- // Check whether minuend and subtrahend are equal.
- for (ListGridRecord record: differencesList.getRecords()) {
- RecommendationPairRecord r = (RecommendationPairRecord) record;
- if (r.getFirst().equals(r.getSecond())) {
- errors.add(MSG.error_same_waterlevels_in_pair());
- }
- }
-
- return errors;
- }
-
-
- /**
- * Creates layout with grid that displays selection inside.
- */
- public Canvas createWidget() {
- VLayout layout = new VLayout();
- differencesList = new ListGrid();
-
- differencesList.setCanEdit(false);
- differencesList.setCanSort(false);
- differencesList.setShowHeaderContextMenu(false);
- differencesList.setHeight(150);
- differencesList.setShowAllRecords(true);
-
- ListGridField nameField = new ListGridField("first", "Minuend");
- ListGridField capitalField = new ListGridField("second", "Subtrahend");
- // Track removed rows, therefore more or less reimplement
- // setCanRecomeRecords.
- final ListGridField removeField =
- new ListGridField("_removeRecord", "Remove Record"){{
- setType(ListGridFieldType.ICON);
- setIcon(GWT.getHostPageBaseURL() + MSG.removeFeature());
- setCanEdit(false);
- setCanFilter(false);
- setCanSort(false);
- setCanGroupBy(false);
- setCanFreeze(false);
- setWidth(25);
- }};
-
- differencesList.setFields(new ListGridField[] {nameField,
- capitalField, removeField});
-
- differencesList.addRecordClickHandler(new RecordClickHandler() {
- @Override
- public void onRecordClick(final RecordClickEvent event) {
- // Just handle remove-clicks
- if(!event.getField().getName()
- .equals(removeField.getName())
- ) {
- return;
- }
- trackRemoved(event.getRecord());
- event.getViewer().removeData(event.getRecord());
- }
- });
- layout.addMember(differencesList);
-
return layout;
}
-
-
- /**
- * Add record to list of removed records.
- */
- public void trackRemoved(Record r) {
- RecommendationPairRecord pr = (RecommendationPairRecord) r;
- this.removedPairs.add(pr);
- }
-
- /**
- * Set factory of recommendation such that the correct artifacts will
- * be cloned for difference calculations.
- */
- public void adjustRecommendation(Recommendation recommendation) {
- // XXX: THIS IS AN EVIL HACK TO MAKE W-DIFFERENCES WORK AGAIN!
- // TODO: Throw all this code away and do it with server side
- // recommendations!
- recommendation.setTargetOut("w_differences");
-
- if (recommendation.getIDs() != null) {
- GWT.log("Setting staticwkms factory for rec with ID "
- + recommendation.getIDs());
- recommendation.setFactory("staticwkms");
- }
- /*
- // So far, we do not need to rewrite the factory anymore,
- // except for staticwkms; probably other cases will pop up later.
- else if (recommendation.getFactory().equals("winfo")) {
- GWT.log("Setting waterlevel factory for a winfo rec.");
- recommendation.setFactory("waterlevel");
- }
- */
- else {
- GWT.log("Leave rec. id " + recommendation.getIDs() + ", factory "
- + recommendation.getFactory() + " untouched.");
- }
- }
-
- /**
- * Validates data, does nothing if invalid, otherwise clones new selected
- * waterlevels and add them to collection, forward the artifact.
- */
- @Override
- public void onClick(ClickEvent e) {
- GWT.log("DatacageTwinPanel.onClick");
-
- List errors = validate();
- if (errors != null && !errors.isEmpty()) {
- showErrors(errors);
- return;
- }
-
- Config config = Config.getInstance();
- String locale = config.getLocale();
-
- ListGridRecord[] records = differencesList.getRecords();
-
- List ar = new ArrayList();
- List all = new ArrayList();
-
- for (ListGridRecord record : records) {
- RecommendationPairRecord r =
- (RecommendationPairRecord) record;
- // Do not add "old" recommendations.
- if (!r.isAlreadyLoaded()) {
- // Check whether one of those is a dike or similar.
- // TODO differentiate and merge: new clones, new, old.
- Recommendation firstR = r.getFirst();
- adjustRecommendation(firstR);
-
- Recommendation secondR = r.getSecond();
- adjustRecommendation(secondR);
- ar.add(firstR);
- ar.add(secondR);
- }
- else {
- all.add(r.getFirst());
- all.add(r.getSecond());
- }
- }
-
- final Recommendation[] toClone = ar.toArray(
- new Recommendation[ar.size()]);
- final Recommendation[] toUse = all.toArray(
- new Recommendation[all.size()]);
-
- // Find out whether "old" artifacts have to be removed.
- List artifactIdsToRemove = new ArrayList();
- for (RecommendationPairRecord rp: this.removedPairs) {
- Recommendation first = rp.getFirst();
- Recommendation second = rp.getSecond();
-
- for (Recommendation recommendation: toUse) {
- if (first != null
- && first.getIDs().equals(recommendation.getIDs())
- ) {
- first = null;
- }
- if (second != null
- && second.getIDs().equals(recommendation.getIDs())
- ) {
- second = null;
- }
-
- if (first == null && second == null) {
- break;
- }
- }
- if (first != null) {
- artifactIdsToRemove.add(first.getIDs());
- }
- if (second != null) {
- artifactIdsToRemove.add(second.getIDs());
- }
- }
-
- // Remove old artifacts, if any. Do this asychronously without much
- // feedback.
- for(final String uuid: artifactIdsToRemove) {
- removeArtifactService.remove(this.collection,
- uuid,
- locale,
- new AsyncCallback() {
- @Override
- public void onFailure(Throwable caught) {
- GWT.log("RemoveArtifact (" + uuid + ") failed.");
- }
- @Override
- public void onSuccess(Collection collection) {
- GWT.log("RemoveArtifact succeeded");
- }
- });
- }
-
- // Clone new ones (and spawn statics), go forward.
- parameterList.lockUI();
- loadArtifactService.loadMany(
- this.collection,
- toClone,
- //"staticwkms" and "waterlevel"
- null,
- locale,
- new AsyncCallback() {
- @Override
- public void onFailure(Throwable caught) {
- GWT.log("Failure of cloning with factories!");
- parameterList.unlockUI();
- }
- @Override
- public void onSuccess(Artifact[] artifacts) {
- GWT.log("Successfully cloned " + toClone.length +
- " with factories.");
-
- fireStepForwardEvent(new StepForwardEvent(
- getData(toClone, artifacts, toUse)));
- parameterList.unlockUI();
- }
- });
- }
-
-
- /**
- * Create Data and DataItem from selection (a long string with identifiers
- * to construct diff-pairs).
- *
- * @param newRecommendations "new" recommendations (did not survive a
- * backjump).
- * @param newArtifacts artifacts cloned from newRecommendations.
- * @param oldRecommendations old recommendations that survived a backjump.
- *
- * @return dataitem with a long string with identifiers to construct
- * diff-pairs.
- */
- protected Data[] getData(
- Recommendation[] newRecommendations,
- Artifact[] newArtifacts,
- Recommendation[] oldRecommendations)
- {
- // Construct string with info about selections.
- String dataItemString = "";
- for (int i = 0; i < newRecommendations.length; i++) {
- Recommendation r = newRecommendations[i];
- Artifact newArtifact = newArtifacts[i];
- String uuid = newArtifact.getUuid();
- r.setMasterArtifact(uuid);
- if (i>0) dataItemString += "#";
-
- dataItemString += createDataString(uuid, r);
- }
-
- for (int i = 0; i < oldRecommendations.length; i++) {
- Recommendation r = oldRecommendations[i];
- String uuid = r.getIDs();
- if (dataItemString.length() > 0) dataItemString += "#";
-
- dataItemString += createDataString(uuid, r);
- }
-
- // TODO some hassle could be resolved by using multiple DataItems
- // (e.g. one per pair).
- DataItem item = new DefaultDataItem(dataName, dataName, dataItemString);
- return new Data[] { new DefaultData(
- dataName, null, null, new DataItem[] {item}) };
- }
-
-
- protected String createDataString(
- String artifact,
- Recommendation recommendation
- ) {
- return createDataString(artifact, recommendation, "staticwkms");
- }
-
- /**
- * Creates part of the String that encodes minuend or subtrahend.
- * @param artifact Artifacts UUID.
- * @param recommendation Recommendation to wrap in string.
- * @param factory The factory to encode.
- */
- protected String createDataString(
- String artifact,
- Recommendation recommendation,
- String factory)
- {
- Filter filter = recommendation.getFilter();
- Facet f = null;
-
- if(filter != null) {
- Map> outs = filter.getOuts();
- Set>> entries = outs.entrySet();
-
- for (Map.Entry> entry: entries) {
- List fs = entry.getValue();
-
- f = fs.get(0);
- if (f != null) {
- break;
- }
- }
-
- return "[" + artifact + ";"
- + f.getName()
- + ";"
- + f.getIndex()
- + ";"
- + recommendation.getDisplayName() + "]";
- }
- else {
- return "["
- + artifact
- + ";" + factory + ";0;"
- + recommendation.getDisplayName() + "]";
- }
- }
-}
-// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
+}
\ No newline at end of file
diff -r 0862ea5d66ba -r 28df64078f27 gwt-client/src/main/java/org/dive4elements/river/client/client/ui/DefaultDatacageTwinPanelInfo.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/DefaultDatacageTwinPanelInfo.java Fri Jan 19 11:23:42 2018 +0100
@@ -0,0 +1,47 @@
+/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
+ * Software engineering by
+ * Björnsen Beratende Ingenieure GmbH
+ * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+package org.dive4elements.river.client.client.ui;
+
+import org.dive4elements.river.client.client.ui.DatacageTwinPanel.IDatacageTwinPanelInfo;
+import org.dive4elements.river.client.shared.model.Recommendation;
+
+/**
+ * @author Gernot Belger
+ */
+public final class DefaultDatacageTwinPanelInfo implements IDatacageTwinPanelInfo {
+
+ private String factory;
+ private String outs;
+
+ public DefaultDatacageTwinPanelInfo(final String factory, final String outs) {
+ this.factory = factory;
+ this.outs = outs;
+ }
+
+ @Override
+ public String getFactory() {
+ return factory;
+ }
+
+ @Override
+ public String getDataStringFactory() {
+ return factory;
+ }
+
+ @Override
+ public void adjustRecommendation(Recommendation recommendation) {
+ recommendation.setFactory(factory);
+ }
+
+ @Override
+ public String getOuts() {
+ return outs;
+ }
+}
\ No newline at end of file
diff -r 0862ea5d66ba -r 28df64078f27 gwt-client/src/main/java/org/dive4elements/river/client/client/ui/ParameterList.java
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/ParameterList.java Thu Jan 18 20:54:03 2018 +0100
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/ParameterList.java Fri Jan 19 11:23:42 2018 +0100
@@ -65,6 +65,7 @@
import org.dive4elements.river.client.shared.model.OutputMode;
import org.dive4elements.river.client.shared.model.ReportMode;
import org.dive4elements.river.client.shared.model.River;
+import org.dive4elements.river.client.shared.model.SINFOArtifact;
import org.dive4elements.river.client.shared.model.WINFOArtifact;
import java.util.ArrayList;
@@ -771,8 +772,11 @@
setCurrentData(null, null);
}
}
+
+ // FIXME: we got a whole artifact framework to separate ui and backend stuff, but in the end.... we have switches over specific datatypes here...
if (art instanceof WINFOArtifact
- || art instanceof FixAnalysisArtifact) {
+ || art instanceof SINFOArtifact
+ || art instanceof FixAnalysisArtifact) {
createGaugePanel();
renderInfo(desc.getRiver(), desc.getOldData());
}
diff -r 0862ea5d66ba -r 28df64078f27 gwt-client/src/main/java/org/dive4elements/river/client/client/ui/UIProviderFactory.java
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/UIProviderFactory.java Thu Jan 18 20:54:03 2018 +0100
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/UIProviderFactory.java Fri Jan 19 11:23:42 2018 +0100
@@ -22,6 +22,7 @@
import org.dive4elements.river.client.client.ui.minfo.SedLoadEpochPanel;
import org.dive4elements.river.client.client.ui.minfo.SedLoadPeriodPanel;
import org.dive4elements.river.client.client.ui.minfo.SedLoadSQTiPanel;
+import org.dive4elements.river.client.client.ui.sinfo.FlowDepthTwinPanel;
import org.dive4elements.river.client.client.ui.sq.SQPeriodPanel;
import org.dive4elements.river.client.shared.model.User;
@@ -86,8 +87,8 @@
else if (uiProvider.equals("dgm_datacage_panel")) {
return new DemDatacagePanel(user);
}
- else if (uiProvider.equals("datacage_twin_panel")) {
- return new DatacageTwinPanel(user);
+ else if (uiProvider.equals("waterlevel_twin_panel")) {
+ return new WaterlevelTwinPanel(user);
}
else if (uiProvider.equals("auto_integer")) {
return new AutoIntegerPanel();
@@ -194,10 +195,12 @@
else if (uiProvider.equals("static_sqrelation")) {
return new StaticDataPanel();
}
- else {
- //GWT.log("Picked default provider.");
- return new SelectProvider();
- }
+
+ if ("sinfo_flowdepth_twin_panel".equals(uiProvider))
+ return new FlowDepthTwinPanel(user);
+
+ //GWT.log("Picked default provider.");
+ return new SelectProvider();
}
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
diff -r 0862ea5d66ba -r 28df64078f27 gwt-client/src/main/java/org/dive4elements/river/client/client/ui/WaterlevelRecommandationInfo.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/WaterlevelRecommandationInfo.java Fri Jan 19 11:23:42 2018 +0100
@@ -0,0 +1,69 @@
+/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
+ * Software engineering by
+ * Björnsen Beratende Ingenieure GmbH
+ * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+package org.dive4elements.river.client.client.ui;
+
+import org.dive4elements.river.client.client.ui.DatacageTwinPanel.IDatacageTwinPanelInfo;
+import org.dive4elements.river.client.shared.model.Recommendation;
+
+import com.google.gwt.core.client.GWT;
+
+/**
+ * @author Gernot Belger
+ */
+public final class WaterlevelRecommandationInfo implements IDatacageTwinPanelInfo {
+
+ private String outs;
+
+ public WaterlevelRecommandationInfo(String outs ) {
+ this.outs = outs;
+ }
+
+ @Override
+ public String getFactory() {
+ // FIXME: why are the factory here and the one used in createDataString different?
+ // Probably also because of the 'throw all this code away comment'
+ return "waterlevel";
+ }
+
+ @Override
+ public String getDataStringFactory() {
+ return "staticwkms";
+ }
+
+ @Override
+ public void adjustRecommendation(Recommendation recommendation) {
+ // XXX: THIS IS AN EVIL HACK TO MAKE W-DIFFERENCES WORK AGAIN!
+ // TODO: Throw all this code away and do it with server side recommendations!
+ recommendation.setTargetOut("w_differences");
+
+ if (recommendation.getIDs() != null) {
+ GWT.log("Setting staticwkms factory for rec with ID "
+ + recommendation.getIDs());
+ recommendation.setFactory("staticwkms");
+ }
+ /*
+ // So far, we do not need to rewrite the factory anymore,
+ // except for staticwkms; probably other cases will pop up later.
+ else if (recommendation.getFactory().equals("winfo")) {
+ GWT.log("Setting waterlevel factory for a winfo rec.");
+ recommendation.setFactory("waterlevel");
+ }
+ */
+ else {
+ GWT.log("Leave rec. id " + recommendation.getIDs() + ", factory "
+ + recommendation.getFactory() + " untouched.");
+ }
+ }
+
+ @Override
+ public String getOuts() {
+ return outs;
+ }
+}
\ No newline at end of file
diff -r 0862ea5d66ba -r 28df64078f27 gwt-client/src/main/java/org/dive4elements/river/client/client/ui/WaterlevelTwinPanel.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/WaterlevelTwinPanel.java Fri Jan 19 11:23:42 2018 +0100
@@ -0,0 +1,25 @@
+/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
+ * Software engineering by
+ * Björnsen Beratende Ingenieure GmbH
+ * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+package org.dive4elements.river.client.client.ui;
+
+import org.dive4elements.river.client.shared.model.User;
+
+/**
+ * A DatacageTwinPanel implementation for W-INFO Differences: choose two waterlevels
+ *
+ * @author Gernot Belger
+ */
+public class WaterlevelTwinPanel
+extends DatacageTwinPanel {
+
+ public WaterlevelTwinPanel(final User user) {
+ super(user, new WaterlevelTwinPanelValidator(), new WaterlevelRecommandationInfo("winfo_diff_twin_panel"), new WaterlevelRecommandationInfo("winfo_diff_twin_panel") );
+ }
+}
\ No newline at end of file
diff -r 0862ea5d66ba -r 28df64078f27 gwt-client/src/main/java/org/dive4elements/river/client/client/ui/WaterlevelTwinPanelValidator.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/WaterlevelTwinPanelValidator.java Fri Jan 19 11:23:42 2018 +0100
@@ -0,0 +1,48 @@
+/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
+ * Software engineering by
+ * Björnsen Beratende Ingenieure GmbH
+ * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+package org.dive4elements.river.client.client.ui;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.dive4elements.river.client.client.FLYSConstants;
+import org.dive4elements.river.client.client.ui.AbstractPairRecommendationPanel.IValidator;
+
+import com.smartgwt.client.widgets.grid.ListGrid;
+import com.smartgwt.client.widgets.grid.ListGridRecord;
+
+/**
+ * Contains the old code from the validate-method of the DatacageTwinPanel.
+ *
+ * @author Gernot Belger
+ */
+public final class WaterlevelTwinPanelValidator implements IValidator {
+
+ @Override
+ public List validate(final ListGrid differencesList, final FLYSConstants msgProvider) {
+
+ final List errors = new ArrayList();
+ if (differencesList.getRecords().length == 0) {
+ // FIXME: waterlevel dependent! This will lead to a bad error message in English, for M-Info/Bed-Differences calculation
+ errors.add(msgProvider.error_no_waterlevel_pair_selected());
+ }
+ // Check whether minuend and subtrahend are equal.
+ for (ListGridRecord record: differencesList.getRecords()) {
+ RecommendationPairRecord r = (RecommendationPairRecord) record;
+ if (r.getFirst().equals(r.getSecond())) {
+ // FIXME: this is still waterlevel specific!
+ // TODO: delegate validation to specific implementations
+ errors.add(msgProvider.error_same_waterlevels_in_pair());
+ }
+ }
+
+ return errors;
+ }
+}
\ No newline at end of file
diff -r 0862ea5d66ba -r 28df64078f27 gwt-client/src/main/java/org/dive4elements/river/client/client/ui/minfo/BedHeightsDatacagePanel.java
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/minfo/BedHeightsDatacagePanel.java Thu Jan 18 20:54:03 2018 +0100
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/minfo/BedHeightsDatacagePanel.java Fri Jan 19 11:23:42 2018 +0100
@@ -8,85 +8,51 @@
package org.dive4elements.river.client.client.ui.minfo;
+import java.util.List;
+
+import org.dive4elements.river.client.client.ui.AbstractPairRecommendationPanel;
+import org.dive4elements.river.client.client.ui.DatacageWidget;
+import org.dive4elements.river.client.client.ui.DefaultDatacageTwinPanelInfo;
+import org.dive4elements.river.client.client.ui.RecommendationPairRecord;
+import org.dive4elements.river.client.client.ui.WaterlevelTwinPanelValidator;
+import org.dive4elements.river.client.shared.model.DataList;
+import org.dive4elements.river.client.shared.model.ToLoad;
+import org.dive4elements.river.client.shared.model.User;
+
import com.google.gwt.core.client.GWT;
-
import com.smartgwt.client.util.SC;
import com.smartgwt.client.widgets.Button;
import com.smartgwt.client.widgets.Canvas;
-
import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.events.ClickHandler;
-
+import com.smartgwt.client.widgets.grid.ListGrid;
import com.smartgwt.client.widgets.layout.VLayout;
import com.smartgwt.client.widgets.tree.TreeNode;
-import org.dive4elements.river.client.client.FLYSConstants;
-
-import org.dive4elements.river.client.client.services.LoadArtifactServiceAsync;
-import org.dive4elements.river.client.client.services.RemoveArtifactServiceAsync;
-
-import org.dive4elements.river.client.client.ui.DatacageTwinPanel;
-import org.dive4elements.river.client.client.ui.DatacageWidget;
-import org.dive4elements.river.client.client.ui.RecommendationPairRecord;
-
-import org.dive4elements.river.client.shared.model.DataList;
-import org.dive4elements.river.client.shared.model.ToLoad;
-
-import org.dive4elements.river.client.shared.model.Recommendation;
-import org.dive4elements.river.client.shared.model.User;
-
-import java.util.ArrayList;
-import java.util.List;
-
-// TODO Probably better to branch off AbstractUIProvider.
public class BedHeightsDatacagePanel
-extends DatacageTwinPanel {
-
- protected static FLYSConstants MSG = GWT.create(FLYSConstants.class);
-
- /**
- * List to track previously selected but now removed pairs. (Needed to
- * be able to identify artifacts that can be removed from the collection.
- */
- protected List removedPairs =
- new ArrayList();
-
- /** Service handle to clone and add artifacts to collection. */
- LoadArtifactServiceAsync loadArtifactService = GWT.create(
- org.dive4elements.river.client.client.services
- .LoadArtifactService.class);
-
- /** Service to remove artifacts from collection. */
- RemoveArtifactServiceAsync removeArtifactService = GWT.create(
- org.dive4elements.river.client.client.services
- .RemoveArtifactService.class);
-
- protected DatacageWidget datacage;
+extends AbstractPairRecommendationPanel {
public BedHeightsDatacagePanel(User user) {
- super(user);
+ // FIXME: This will lead to a bad error message in English (i.e. contains something about waterlevels), for M-Info/Bed-Differences calculation
+ // BUT: this is the behavior of 3.2.1 (because of sloppy derivation), so we do not change it now
+ super(user, new WaterlevelTwinPanelValidator(), new DefaultDatacageTwinPanelInfo("bedheight", null), new DefaultDatacageTwinPanelInfo("bedheight", null) );
}
- /**
- * Creates graphical representation and interaction widgets for the data.
- * @param dataList the data.
- * @return graphical representation and interaction widgets for data.
- */
@Override
- public Canvas create(DataList dataList) {
+ protected Canvas createChooserWidgets(final Canvas widget, final DataList dataList, final User user, final ListGrid differencesList) {
GWT.log("createData()");
- Canvas widget = createWidget();
Canvas submit = getNextButton();
- datacage = new DatacageWidget(
+
+ final DatacageWidget datacage = new DatacageWidget(
this.artifact, user, "minfo_diff_panel", "load-system:true", false);
- Button plusBtn = new Button(MSG.datacage_add_pair());
+ Button plusBtn = new Button(msg().datacage_add_pair());
plusBtn.setAutoFit(true);
plusBtn.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
- plusClicked();
+ plusClicked(datacage, differencesList);
}
});
@@ -100,32 +66,19 @@
layout.setMembersMargin(10);
this.helperContainer.addMember(helperLayout);
- populateGrid(dataList, "bedheight");
-
return layout;
}
- public void adjustRecommendation(Recommendation recommendation) {
- recommendation.setFactory("bedheight");
- }
-
- @Override
- protected String createDataString(
- String artifact,
- Recommendation recommendation
- ) {
- return createDataString(artifact, recommendation, "bedheight");
- }
-
/**
* Callback for add-button.
* Fires to load for every selected element and handler.
+ * @param differencesList
*/
- public void plusClicked() {
+ protected final static void plusClicked( final DatacageWidget datacage, ListGrid differencesList ) {
List selection = datacage.getPlainSelection();
if (selection == null || selection.isEmpty()) {
- SC.say(MSG.warning());
+ SC.say(msg().warning());
return;
}
diff -r 0862ea5d66ba -r 28df64078f27 gwt-client/src/main/java/org/dive4elements/river/client/client/ui/sinfo/FlowDepthTwinPanel.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/sinfo/FlowDepthTwinPanel.java Fri Jan 19 11:23:42 2018 +0100
@@ -0,0 +1,25 @@
+/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
+ * Software engineering by
+ * Björnsen Beratende Ingenieure GmbH
+ * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+package org.dive4elements.river.client.client.ui.sinfo;
+
+import org.dive4elements.river.client.client.ui.DatacageTwinPanel;
+import org.dive4elements.river.client.client.ui.DefaultDatacageTwinPanelInfo;
+import org.dive4elements.river.client.client.ui.WaterlevelRecommandationInfo;
+import org.dive4elements.river.client.shared.model.User;
+
+/**
+ * @author Gernot Belger
+ */
+public class FlowDepthTwinPanel
+extends DatacageTwinPanel {
+ public FlowDepthTwinPanel(final User user) {
+ super(user, new FlowDepthTwinPanelValidator(), new WaterlevelRecommandationInfo("sinfo_flowdepth_waterlevels"), new DefaultDatacageTwinPanelInfo("bedheight", "sinfo_flowdepth_minfo_heights") );
+ }
+}
\ No newline at end of file
diff -r 0862ea5d66ba -r 28df64078f27 gwt-client/src/main/java/org/dive4elements/river/client/client/ui/sinfo/FlowDepthTwinPanelValidator.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/sinfo/FlowDepthTwinPanelValidator.java Fri Jan 19 11:23:42 2018 +0100
@@ -0,0 +1,39 @@
+/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
+ * Software engineering by
+ * Björnsen Beratende Ingenieure GmbH
+ * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+package org.dive4elements.river.client.client.ui.sinfo;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.dive4elements.river.client.client.FLYSConstants;
+import org.dive4elements.river.client.client.ui.AbstractPairRecommendationPanel.IValidator;
+
+import com.smartgwt.client.widgets.grid.ListGrid;
+import com.smartgwt.client.widgets.grid.ListGridRecord;
+
+/**
+ * Contains the old code from the validate-method of the DatacageTwinPanel.
+ *
+ * @author Gernot Belger
+ */
+final class FlowDepthTwinPanelValidator implements IValidator {
+
+ @Override
+ public List validate(final ListGrid differencesList, final FLYSConstants msgProvider) {
+
+ final List errors = new ArrayList();
+ if (differencesList.getRecords().length == 0) {
+ // FIXME: waterlevel dependent! This will lead to a bad error message in English, for M-Info/Bed-Differences calculation
+ errors.add(msgProvider.sinfo_flowdepth_twinpanel_no_pair_selected());
+ }
+
+ return errors;
+ }
+}
\ No newline at end of file
diff -r 0862ea5d66ba -r 28df64078f27 gwt-client/src/main/java/org/dive4elements/river/client/server/FLYSArtifactCreator.java
--- a/gwt-client/src/main/java/org/dive4elements/river/client/server/FLYSArtifactCreator.java Thu Jan 18 20:54:03 2018 +0100
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/server/FLYSArtifactCreator.java Fri Jan 19 11:23:42 2018 +0100
@@ -31,6 +31,7 @@
import org.dive4elements.river.client.shared.model.FixAnalysisArtifact;
import org.dive4elements.river.client.shared.model.GaugeDischargeCurveArtifact;
import org.dive4elements.river.client.shared.model.MapArtifact;
+import org.dive4elements.river.client.shared.model.SINFOArtifact;
import org.dive4elements.river.client.shared.model.MINFOArtifact;
import org.dive4elements.river.client.shared.model.StaticSQRelationArtifact;
import org.dive4elements.river.client.shared.model.WINFOArtifact;
@@ -134,35 +135,47 @@
name = name.trim();
- if (name.length() > 0 && name.equals("winfo")) {
+ // FIXME: why do we have a super sophisticated artifact-framework if, in the end, module dependent stuff is still switched manually....
+ if (name.equals("winfo")) {
log.debug("+++++ NEW WINFO ARTIFACT.");
return new WINFOArtifact(uuid, hash, background, msg);
}
- else if (name.length() > 0 && name.equals("new_map")) {
+
+ if (name.equals("new_map")) {
log.debug("+++++ NEW MAP ARTIFACT.");
return new MapArtifact(uuid, hash, background, msg);
}
- else if (name.length() > 0 && name.equals("new_chart")) {
+
+ if (name.equals("new_chart")) {
log.debug("+++++ NEW CHART ARTIFACT.");
return new ChartArtifact(uuid, hash, background, msg);
}
- else if (name.length() > 0 && name.equals("minfo")) {
+
+ if (name.equals("minfo")) {
log.debug("+++++ NEW MINFO ARTIFACT.");
return new MINFOArtifact(uuid, hash, background, msg);
}
- else if (name.length() > 0 && name.equals("fixanalysis")) {
+
+ if (name.equals("fixanalysis")) {
log.debug("+++++ NEW FIXANALYSIS ARTIFACT.");
return new FixAnalysisArtifact(uuid, hash, background, msg);
}
- else if (name.length() > 0 && name.equals("gaugedischargecurve")) {
+
+ if (name.equals("gaugedischargecurve")) {
log.debug("+++++ NEW GAUGEDISCHARGECURVE ARTIFACT.");
return new GaugeDischargeCurveArtifact(uuid, hash, background, msg);
}
- else if (name.length() > 0 && name.equals("staticsqrelation")) {
+
+ if (name.equals("staticsqrelation")) {
log.debug("+++++ STATICSQRELATION ARTIFACT.");
return new StaticSQRelationArtifact(uuid, hash, background, msg);
}
+ if (name.equals("sinfo")) {
+ log.debug("+++++ NEW SINFO ARTIFACT.");
+ return new SINFOArtifact(uuid, hash, background, msg);
+ }
+
return new DefaultArtifact(uuid, hash, background, msg);
}
diff -r 0862ea5d66ba -r 28df64078f27 gwt-client/src/main/java/org/dive4elements/river/client/server/auth/UserClient.java
--- a/gwt-client/src/main/java/org/dive4elements/river/client/server/auth/UserClient.java Thu Jan 18 20:54:03 2018 +0100
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/server/auth/UserClient.java Fri Jan 19 11:23:42 2018 +0100
@@ -84,6 +84,8 @@
account.setAttribute("name", user.getAccount());
//TODO create roles
+ // FIXME: not creating the roles will write an broken xmldocument (only header) into the artifacts db
+ // which in turn will result in an exception (which is handled)
artuser.appendChild(account);
action.appendChild(type);
action.appendChild(artuser);
diff -r 0862ea5d66ba -r 28df64078f27 gwt-client/src/main/java/org/dive4elements/river/client/shared/model/SINFOArtifact.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/shared/model/SINFOArtifact.java Fri Jan 19 11:23:42 2018 +0100
@@ -0,0 +1,46 @@
+/* Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
+ * Software engineering by Intevation GmbH
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+
+package org.dive4elements.river.client.shared.model;
+
+import java.util.List;
+
+
+/**
+ * The SINFO implementation of an Artifact.
+ *
+ * @author Gernot Belger
+ */
+public class SINFOArtifact extends DefaultArtifact {
+
+ /** The name of this artifact: 'sinfo'.*/
+ private static final String NAME = "sinfo";
+
+ /** Necessary for serialization */
+ public SINFOArtifact() {
+ }
+
+// public SINFOArtifact(String uuid, String hash) {
+// super(uuid, hash);
+// }
+
+ public SINFOArtifact(
+ String uuid,
+ String hash,
+ boolean inBackground,
+ List messages
+ ) {
+ super(uuid, hash, inBackground, messages);
+ }
+
+
+ public String getName() {
+ return NAME;
+ }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
diff -r 0862ea5d66ba -r 28df64078f27 gwt-client/src/main/webapp/WEB-INF/features.xml
--- a/gwt-client/src/main/webapp/WEB-INF/features.xml Thu Jan 18 20:54:03 2018 +0100
+++ b/gwt-client/src/main/webapp/WEB-INF/features.xml Fri Jan 19 11:23:42 2018 +0100
@@ -1,6 +1,7 @@
+ module:sinfo
module:winfo
module:minfo
module:new_map
diff -r 0862ea5d66ba -r 28df64078f27 gwt-client/src/main/webapp/WEB-INF/log4j.properties
--- a/gwt-client/src/main/webapp/WEB-INF/log4j.properties Thu Jan 18 20:54:03 2018 +0100
+++ b/gwt-client/src/main/webapp/WEB-INF/log4j.properties Fri Jan 19 11:23:42 2018 +0100
@@ -1,18 +1,15 @@
log4j.rootLogger=DEBUG, FLYS
########## INTERNAL PACKAGES
-log4j.category.de.intevation.flys.client.server=DEBUG
-
+log4j.category.org.dive4elements.river.client.server=DEBUG
########## EXTERNAL PACKAGES
log4j.category.org.apache.http=ERROR
-log4j.category.de.intevation.artifacts.httpclient=WARN
+log4j.category.org.dive4elements.artifacts.httpclient=WARN
########## APPENDER SETTINGS
log4j.appender.FLYS.layout=org.apache.log4j.PatternLayout
log4j.appender.FLYS.layout.ConversionPattern=%d [%t] %-5p %c - %m%n
-log4j.appender.FLYS=org.apache.log4j.RollingFileAppender
-log4j.appender.FLYS.File=/var/log/d4e-river/d4e-client.log
-log4j.appender.FLYS.MaxFileSize=5000KB
-log4j.appender.FLYS.MaxBackupIndex=3
+log4j.appender.FLYS=org.apache.log4j.ConsoleAppender
+log4j.appender.FLYS.Target = System.out
diff -r 0862ea5d66ba -r 28df64078f27 gwt-client/src/main/webapp/WEB-INF/web.xml
--- a/gwt-client/src/main/webapp/WEB-INF/web.xml Thu Jan 18 20:54:03 2018 +0100
+++ b/gwt-client/src/main/webapp/WEB-INF/web.xml Fri Jan 19 11:23:42 2018 +0100
@@ -85,6 +85,8 @@
/flys/user
+
+
server-info
org.dive4elements.river.client.server.ServerInfoServiceImpl