changeset 9299:4a6cc7c6716a

uinfo.inundation_duration veg'zone select
author gernotbelger
date Wed, 25 Jul 2018 14:42:44 +0200
parents 0b1a51b0c42e
children 68e216b842ac
files artifacts/doc/conf/meta-data.xml artifacts/src/main/java/org/dive4elements/river/artifacts/datacage/templating/DataFromArtifactXPathFunction.java artifacts/src/main/java/org/dive4elements/river/artifacts/datacage/templating/DefaultVegetationZoneXPathFunction.java artifacts/src/main/java/org/dive4elements/river/artifacts/datacage/templating/FunctionResolver.java artifacts/src/main/java/org/dive4elements/river/exports/WstWriter.java gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.java gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.properties gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants_de.properties gwt-client/src/main/java/org/dive4elements/river/client/client/ui/UIProviderFactory.java gwt-client/src/main/java/org/dive4elements/river/client/client/ui/uinfo/AbstractVegZonesTablePanel.java gwt-client/src/main/java/org/dive4elements/river/client/client/ui/uinfo/VegetationzonesTableEditPanel.java gwt-client/src/main/java/org/dive4elements/river/client/client/ui/uinfo/VegetationzonesTablePanel.java gwt-client/src/main/webapp/WEB-INF/web.xml
diffstat 13 files changed, 499 insertions(+), 307 deletions(-) [+]
line wrap: on
line diff
--- a/artifacts/doc/conf/meta-data.xml	Wed Jul 25 11:33:48 2018 +0200
+++ b/artifacts/doc/conf/meta-data.xml	Wed Jul 25 14:42:44 2018 +0200
@@ -142,7 +142,7 @@
                   <dc:when test="$out = 'sinfo_flood_height'">
                     <dc:call-macro name="annotations" />
                   </dc:when>
-                  
+
                   <dc:when test="$out = 'uinfo_salix_line'">
                     <dc:call-macro name="annotations" />
                   </dc:when>
@@ -322,10 +322,14 @@
                   <dc:when test="$out = 'sinfo_flood_duration_curve'">
                     <dc:call-macro name="longitudinal-section-prototype" />
                   </dc:when>
-                  
+
                   <dc:when test="$out = 'uinfo_salix_line'">
                     <dc:call-macro name="longitudinal-section-prototype" />
                   </dc:when>
+                  <dc:when test="$out = 'uinfo.inundation_duration.vegzoneselect'">
+                    <dc:variable name="vegzonedata" expr="dc:defaultvegetationzone()"></dc:variable>
+                    <defaultVegetationZone factory="dummy" target_out="{$out}" data="{$vegzonedata}"></defaultVegetationZone>
+                  </dc:when>
                 </dc:choose>
               </dc:iterate>
             </dc:otherwise>
@@ -421,6 +425,9 @@
                     <dc:when test="$out = 'sinfo_tkk'">
                       <dc:call-macro name="longitudinal-section-user-prototype" />
                     </dc:when>
+                    <dc:when test="$out = 'uinfo.inundation_duration.vegzoneselect'">
+                      <dc:call-macro name="vegetationzones" />
+                    </dc:when>
                     <dc:comment> Discharge curves </dc:comment>
                     <dc:when test="$out = 'computed_discharge_curve'">
                       <dc:call-macro name="discharge-curve-user-prototype" />
@@ -1445,7 +1452,7 @@
 
     <dc:macro name="basedata_3_officials">
       <dc:call-macro name="basedata_3_macro">
-        <dc:variable name="start_year" expr="dc:date-format('yyyy', $start_time)" />      
+        <dc:variable name="start_year" expr="dc:date-format('yyyy', $start_time)" />
         <column name="{$wst_column_name}" ids="additionals-wstv-{$wst_column_position}-{$wst_id}" factory="staticwqkms" target_out="{$out}" info="{$info} [km {$deffrom} - {$defto}]" year="{dc:date-format('yyyy', $start_time)}" />
       </dc:call-macro>
     </dc:macro>
@@ -1577,7 +1584,7 @@
 
     <dc:macro name="basedata_7_waterlevels">
       <dc:call-macro name="basedata_7_macro">
-        <dc:variable name="start_year" expr="dc:date-format('yyyy', $start_time)" />      
+        <dc:variable name="start_year" expr="dc:date-format('yyyy', $start_time)" />
         <column name="{$wst_column_name}" ids="additionals-wstv-{$wst_column_position}-{$wst_id}" factory="staticwqkms" target_out="{$out}" info="{$info} [km {$deffrom} - {$defto}]" year="{dc:date-format('yyyy', $start_time)}" />
       </dc:call-macro>
     </dc:macro>
@@ -2075,7 +2082,7 @@
     <dc:macro name="bed-heights-single">
       <single>
         <dc:context>
-          <dc:call-macro name="bed-heights-statement" />  
+          <dc:call-macro name="bed-heights-statement" />
           <dc:if test="dc:has-result()">
             <dc:group expr="dc:coalesce($bedh_year, 'sonstige')">
               <heights name="{dc:group-key()}" description="{dc:group-key()}">
@@ -3224,8 +3231,9 @@
           w.sinfo_selection
           FROM wst_columns wc
           JOIN wsts w ON wc.wst_id = w.id
-          JOIN wst_ranges wr ON wc.id = wr.wst_column_id
-          LEFT JOIN time_intervals ti ON wc.time_interval_id = ti.id          
+          JOIN wst_ranges wr ON wc.id =
+          wr.wst_column_id
+          LEFT JOIN time_intervals ti ON wc.time_interval_id = ti.id
           WHERE w.river_id = ${river_id} AND
           NOT((${tokm} &lt; wr.a) or (${fromkm} &gt; wr.b))
           ORDER BY wst_column_position
@@ -3477,7 +3485,8 @@
           FROM channel s
           INNER JOIN channel_values v ON s.id=v.channel_id
           WHERE (s.river_id=${river_id})
-          AND (v.station BETWEEN ${fromkm}-0.0001 AND ${tokm}+0.0001)
+          AND (v.station BETWEEN ${fromkm}-0.0001
+          AND ${tokm}+0.0001)
           GROUP BY s.id
           ORDER BY MIN(s.year_to) DESC
         </dc:statement>
@@ -3515,7 +3524,8 @@
           || MIN(s.evaluation_by) AS info
           FROM tkh_column sc
           INNER JOIN tkh s ON sc.tkh_id=s.id
-          INNER JOIN tkh_values v ON sc.id=v.tkh_column_id
+          INNER JOIN tkh_values
+          v ON sc.id=v.tkh_column_id
           WHERE (s.river_id=${river_id})
           AND (lower(s.groupname)=${tkh_groupname})
           AND (v.station BETWEEN ${fromkm}-0.0001 AND ${tokm}+0.0001)
@@ -3588,7 +3598,8 @@
           || MIN(s.sounding_info) || '&lt;br /&gt;'
           || MIN(s.evaluation_by) AS info
           FROM flow_depth_column sc
-          INNER JOIN flow_depth s ON sc.flow_depth_id=s.id
+          INNER JOIN
+          flow_depth s ON sc.flow_depth_id=s.id
           INNER JOIN flow_depth_values v ON sc.id=v.flow_depth_column_id
           WHERE (s.river_id=${river_id})
           AND (v.station BETWEEN ${fromkm}-0.0001 AND ${tokm}+0.0001)
@@ -3644,7 +3655,8 @@
           FROM collision s
           INNER JOIN collision_values v ON s.id=v.collision_id
           WHERE (s.river_id=${river_id})
-          AND (v.station BETWEEN ${fromkm}-0.0001 AND ${tokm}+0.0001)
+          AND (v.station BETWEEN ${fromkm}-0.0001 AND
+          ${tokm}+0.0001)
           GROUP BY s.id
           ORDER BY MIN(s.year)
         </dc:statement>
@@ -3656,5 +3668,33 @@
       </dc:context>
     </dc:macro>
 
+    <!-- Vegetation zones, edited by the user -->
+    <dc:macro name="vegetationzones">
+      <dc:filter expr="$a_state = 'state.uinfo.vegetation_zones' and $facet_name = 'csv'"> <!-- we misuse the csv-facet -->
+        <dc:if test="dc:has-result()">
+          <dc:for-each>
+            <dc:variable name="vegzonedata" expr="dc:data_from_artifact($a_gid,'vegzones')" />
+            <dc:variable name="vegzonedatalabel" expr="dc:get('ld_from'))" />
+            <dc:variable name="label_temp" type="string" expr="dc:coalesce($collection_name, dc:toString($a_gid))" />
+
+            <dc:element name="${facet_name}">
+              <dc:attribute name="factory" value="dummy" />
+              <dc:attribute name="target_out" value="${out}" /> 
+              <dc:attribute name="description" value="${label_temp}" />
+              <!--
+
+                <dc:attribute name="ids" value="${facet_num}" />
+                <dc:attribute name="artifact-id" value="${a_gid}" />
+                <dc:attribute name="out" value="${out_name}" />
+              -->
+
+              <!-- veg zones string as attribute -->
+              <dc:attribute name="data" value="${vegzonedata}" />
+            </dc:element>
+          </dc:for-each>
+        </dc:if>
+      </dc:filter>
+    </dc:macro>
+
   </datacage>
 </dc:template>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/datacage/templating/DataFromArtifactXPathFunction.java	Wed Jul 25 14:42:44 2018 +0200
@@ -0,0 +1,56 @@
+/** 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.datacage.templating;
+
+import java.util.List;
+import java.util.UUID;
+
+import javax.xml.xpath.XPathFunction;
+import javax.xml.xpath.XPathFunctionException;
+
+import org.dive4elements.artifactdatabase.data.StateData;
+import org.dive4elements.artifacts.CallContext;
+import org.dive4elements.river.artifacts.D4EArtifact;
+import org.dive4elements.river.utils.RiverUtils;
+
+/**
+ * Very specialized function the resolves the 'year' (als middle of all used events) from a fix-analysis-vollmer
+ * artifact).
+ *
+ * @author Gernot Belger
+ */
+public class DataFromArtifactXPathFunction implements XPathFunction {
+
+    public static final String ID = "data_from_artifact";
+
+    public static final int ARITY = 2;
+
+    private final CallContext context;
+
+    public DataFromArtifactXPathFunction(final CallContext context) {
+        this.context = context;
+    }
+
+    @Override
+    public Object evaluate(final List args) throws XPathFunctionException {
+
+        final UUID uuid = (UUID) args.get(0);
+        if (uuid == null)
+            return null;
+
+        final D4EArtifact artifact = RiverUtils.getArtifact(uuid.toString(), this.context);
+        if (!(args.get(1) instanceof String))
+            return null;
+
+        final StateData data = artifact.getData(args.get(1).toString());
+        return data.getValue();
+
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/datacage/templating/DefaultVegetationZoneXPathFunction.java	Wed Jul 25 14:42:44 2018 +0200
@@ -0,0 +1,35 @@
+/** 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.datacage.templating;
+
+import java.util.List;
+
+import javax.xml.xpath.XPathFunction;
+import javax.xml.xpath.XPathFunctionException;
+
+import org.dive4elements.river.artifacts.uinfo.vegetationzones.VegetationZone;
+
+/**
+ * Very specialized function the resolves the 'year' (als middle of all used events) from a fix-analysis-vollmer
+ * artifact).
+ *
+ * @author Gernot Belger
+ */
+public class DefaultVegetationZoneXPathFunction implements XPathFunction {
+
+    public static final String ID = "defaultvegetationzone";
+
+    public static final int ARITY = 0;
+
+    @Override
+    public Object evaluate(final List args) throws XPathFunctionException {
+        return VegetationZone.parseListToDataString(VegetationZone.getStandardList());
+    }
+}
\ No newline at end of file
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/datacage/templating/FunctionResolver.java	Wed Jul 25 11:33:48 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/datacage/templating/FunctionResolver.java	Wed Jul 25 14:42:44 2018 +0200
@@ -8,23 +8,21 @@
 
 package org.dive4elements.river.artifacts.datacage.templating;
 
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Date;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.HashMap;
 import java.util.Set;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
 import javax.xml.namespace.QName;
-
 import javax.xml.xpath.XPathFunction;
 import javax.xml.xpath.XPathFunctionException;
 import javax.xml.xpath.XPathFunctionResolver;
@@ -35,11 +33,8 @@
 import org.dive4elements.river.artifacts.context.RiverContext;
 import org.dive4elements.river.artifacts.context.RiverContextFactory;
 
-
 /** Resolves functions (e.g. dc:contains) in Datacage/Meta-Data system. */
-public class FunctionResolver
-implements   XPathFunctionResolver
-{
+public class FunctionResolver implements XPathFunctionResolver {
     /** Home log. */
     private static Logger log = Logger.getLogger(FunctionResolver.class);
 
@@ -49,17 +44,17 @@
 
     protected static final class Entry {
 
-        Entry         next;
+        Entry next;
         XPathFunction function;
-        int           arity;
+        int arity;
 
-        public Entry(Entry next, XPathFunction function, int arity) {
-            this.next     = next;
+        public Entry(final Entry next, final XPathFunction function, final int arity) {
+            this.next = next;
             this.function = function;
-            this.arity    = arity;
+            this.arity = arity;
         }
 
-        XPathFunction find(int arity) {
+        XPathFunction find(final int arity) {
             Entry current = this;
             while (current != null) {
                 if (current.arity == arity) {
@@ -76,107 +71,113 @@
 
     protected Builder.BuildHelper buildHelper;
 
-
     public FunctionResolver() {
         this(null);
     }
 
-    public FunctionResolver(Builder.BuildHelper buildHelper) {
+    public FunctionResolver(final Builder.BuildHelper buildHelper) {
         this.buildHelper = buildHelper;
 
-        functions = new HashMap<String, Entry>();
+        this.functions = new HashMap<>();
 
         addFunction("coalesce", 2, new XPathFunction() {
             @Override
-            public Object evaluate(List args) throws XPathFunctionException {
+            public Object evaluate(final List args) throws XPathFunctionException {
                 return coalesce(args);
             }
         });
 
+        addFunction("toString", 1, new XPathFunction() {
+            @Override
+            public Object evaluate(final List args) throws XPathFunctionException {
+                final Object arg = args.get(0);
+                return arg == null ? null : arg.toString();
+            }
+        });
+
         addFunction("lowercase", 1, new XPathFunction() {
             @Override
-            public Object evaluate(List args) throws XPathFunctionException {
+            public Object evaluate(final List args) throws XPathFunctionException {
                 return args.get(0).toString().toLowerCase();
             }
         });
 
         addFunction("uppercase", 1, new XPathFunction() {
             @Override
-            public Object evaluate(List args) throws XPathFunctionException {
+            public Object evaluate(final List args) throws XPathFunctionException {
                 return args.get(0).toString().toUpperCase();
             }
         });
 
         addFunction("contains", 2, new XPathFunction() {
             @Override
-            public Object evaluate(List args) throws XPathFunctionException {
+            public Object evaluate(final List args) throws XPathFunctionException {
                 return contains(args);
             }
         });
 
         addFunction("fromValue", 3, new XPathFunction() {
             @Override
-            public Object evaluate(List args) throws XPathFunctionException {
+            public Object evaluate(final List args) throws XPathFunctionException {
                 return fromValue(args);
             }
         });
 
         addFunction("toValue", 3, new XPathFunction() {
             @Override
-            public Object evaluate(List args) throws XPathFunctionException {
+            public Object evaluate(final List args) throws XPathFunctionException {
                 return toValue(args);
             }
         });
 
         addFunction("replace", 3, new XPathFunction() {
             @Override
-            public Object evaluate(List args) throws XPathFunctionException {
+            public Object evaluate(final List args) throws XPathFunctionException {
                 return replace(args);
             }
         });
 
         addFunction("replace-all", 3, new XPathFunction() {
             @Override
-            public Object evaluate(List args) throws XPathFunctionException {
+            public Object evaluate(final List args) throws XPathFunctionException {
                 return replaceAll(args);
             }
         });
 
         addFunction("has-result", 0, new XPathFunction() {
             @Override
-            public Object evaluate(List args) throws XPathFunctionException {
+            public Object evaluate(final List args) throws XPathFunctionException {
                 return FunctionResolver.this.buildHelper.hasResult();
             }
         });
 
         addFunction("group-key", 0, new XPathFunction() {
             @Override
-            public Object evaluate(List args) throws XPathFunctionException {
+            public Object evaluate(final List args) throws XPathFunctionException {
                 return FunctionResolver.this.buildHelper.getGroupKey();
             }
         });
 
         addFunction("date-format", 2, new XPathFunction() {
             @Override
-            public Object evaluate(List args) throws XPathFunctionException {
+            public Object evaluate(final List args) throws XPathFunctionException {
                 return dateFormat(args);
             }
         });
 
         addFunction("dump-variables", 0, new XPathFunction() {
             @Override
-            public Object evaluate(List args) throws XPathFunctionException {
+            public Object evaluate(final List args) throws XPathFunctionException {
                 return FunctionResolver.this.buildHelper.frames.dump();
             }
         });
 
         addFunction("get", 1, new XPathFunction() {
             @Override
-            public Object evaluate(List args) throws XPathFunctionException {
-                Object o = args.get(0);
+            public Object evaluate(final List args) throws XPathFunctionException {
+                final Object o = args.get(0);
                 if (o instanceof String) {
-                    return FunctionResolver.this.buildHelper.frames.getNull(
-                        (String)o, StackFrames.NULL);
+                    return FunctionResolver.this.buildHelper.frames.getNull((String) o, StackFrames.NULL);
                 }
                 return StackFrames.NULL;
             }
@@ -184,106 +185,104 @@
 
         addFunction("all-state-successors", 2, new XPathFunction() {
             @Override
-            public Object evaluate(List args) throws XPathFunctionException {
-                Object artifactName  = args.get(0);
-                Object stateId       = args.get(1);
+            public Object evaluate(final List args) throws XPathFunctionException {
+                final Object artifactName = args.get(0);
+                final Object stateId = args.get(1);
 
-                return artifactName instanceof String
-                    && stateId      instanceof String
-                    ? allStateSuccessors((String)artifactName, (String)stateId)
-                    : Collections.<String>emptySet();
+                return artifactName instanceof String && stateId instanceof String ? allStateSuccessors((String) artifactName, (String) stateId)
+                        : Collections.<String>emptySet();
             }
         });
 
         addFunction("find-all", 2, new XPathFunction() {
             @Override
-            public Object evaluate(List args) throws XPathFunctionException {
-                Object needle    = args.get(0);
-                Object haystack  = args.get(1);
-                return haystack instanceof String
-                    && needle   instanceof String
-                    ? findAll((String)needle, (String)haystack)
-                    : Collections.<String>emptyList();
+            public Object evaluate(final List args) throws XPathFunctionException {
+                final Object needle = args.get(0);
+                final Object haystack = args.get(1);
+                return haystack instanceof String && needle instanceof String ? findAll((String) needle, (String) haystack) : Collections.<String>emptyList();
             }
         });
 
         addFunction("max-number", 1, new XPathFunction() {
             @Override
-            public Object evaluate(List args) throws XPathFunctionException {
+            public Object evaluate(final List args) throws XPathFunctionException {
                 return maxNumber(args.get(0));
             }
         });
 
         addFunction("min-number", 1, new XPathFunction() {
             @Override
-            public Object evaluate(List args) throws XPathFunctionException {
+            public Object evaluate(final List args) throws XPathFunctionException {
                 return minNumber(args.get(0));
             }
         });
 
         addFunction("column", 1, new XPathFunction() {
             @Override
-            public Object evaluate(List args) throws XPathFunctionException {
+            public Object evaluate(final List args) throws XPathFunctionException {
                 return column(args.get(0));
             }
         });
 
         addFunction(FixAnalysisYearXPathFunction.ID, FixAnalysisYearXPathFunction.ARITY, new FixAnalysisYearXPathFunction(buildHelper.getContext()));
+
+        addFunction(DefaultVegetationZoneXPathFunction.ID, DefaultVegetationZoneXPathFunction.ARITY, new DefaultVegetationZoneXPathFunction());
+
+        addFunction(DataFromArtifactXPathFunction.ID, DataFromArtifactXPathFunction.ARITY, new DataFromArtifactXPathFunction(buildHelper.getContext()));
     }
 
     /**
      * Create a new function.
-     * @param name  Name of the function.
-     * @param arity Number of arguments for function.
-     * @param function the function itself.
+     *
+     * @param name
+     *            Name of the function.
+     * @param arity
+     *            Number of arguments for function.
+     * @param function
+     *            the function itself.
      */
-    public void addFunction(String name, int arity, XPathFunction function) {
-        Entry entry = functions.get(name);
+    public void addFunction(final String name, final int arity, final XPathFunction function) {
+        Entry entry = this.functions.get(name);
         if (entry == null) {
             entry = new Entry(null, function, arity);
-            functions.put(name, entry);
-        }
-        else {
-            Entry newEntry = new Entry(entry.next, function, arity);
+            this.functions.put(name, entry);
+        } else {
+            final Entry newEntry = new Entry(entry.next, function, arity);
             entry.next = newEntry;
         }
     }
 
     @Override
-    public XPathFunction resolveFunction(QName functionName, int arity) {
+    public XPathFunction resolveFunction(final QName functionName, final int arity) {
 
         if (!functionName.getNamespaceURI().equals(FUNCTION_NAMESPACE_URI)) {
             return null;
         }
 
-        Entry entry = functions.get(functionName.getLocalPart());
-        return entry != null
-            ? entry.find(arity)
-            : null;
+        final Entry entry = this.functions.get(functionName.getLocalPart());
+        return entry != null ? entry.find(arity) : null;
     }
 
     /** Implementation of case-ignoring dc:contains. */
-    public static Object contains(List args) throws XPathFunctionException {
-        Object haystack = args.get(0);
-        Object needle   = args.get(1);
+    public static Object contains(final List args) throws XPathFunctionException {
+        final Object haystack = args.get(0);
+        Object needle = args.get(1);
 
         if (needle instanceof String && !(haystack instanceof String)) {
-            needle = ((String)needle).toUpperCase();
+            needle = ((String) needle).toUpperCase();
         }
 
         try {
             if (haystack instanceof Collection) {
-                return Boolean.valueOf(
-                    ((Collection)haystack).contains(needle));
+                return Boolean.valueOf(((Collection) haystack).contains(needle));
             }
 
             if (haystack instanceof Map) {
-                return Boolean.valueOf(
-                    ((Map)haystack).containsKey(needle));
+                return Boolean.valueOf(((Map) haystack).containsKey(needle));
             }
 
-            if (haystack instanceof Object []) {
-                for (Object straw: (Object [])haystack) {
+            if (haystack instanceof Object[]) {
+                for (final Object straw : (Object[]) haystack) {
                     if (straw.equals(needle)) {
                         return Boolean.TRUE;
                     }
@@ -291,311 +290,294 @@
             }
 
             if (haystack instanceof String && needle instanceof String) {
-                String h = (String)haystack;
-                String n = (String)needle;
+                final String h = (String) haystack;
+                final String n = (String) needle;
                 return h.contains(n);
             }
 
             return Boolean.FALSE;
         }
-        catch (Exception e) {
+        catch (final Exception e) {
             log.error(e);
             throw new XPathFunctionException(e);
         }
     }
 
-    /** Implementation for getting the minimum value of location or distance
-     *  dc:fromValue.
+    /**
+     * Implementation for getting the minimum value of location or distance
+     * dc:fromValue.
      */
-    public static Object fromValue(List args) throws XPathFunctionException {
-        Object mode      = args.get(0);
-        Object locations = args.get(1);
-        Object from      = args.get(2);
+    public static Object fromValue(final List args) throws XPathFunctionException {
+        final Object mode = args.get(0);
+        final Object locations = args.get(1);
+        final Object from = args.get(2);
 
-        if ((mode instanceof String && mode.equals("location")) ||
-            (locations instanceof String && !((String)locations).isEmpty())) {
+        if ((mode instanceof String && mode.equals("location")) || (locations instanceof String && !((String) locations).isEmpty())) {
             if (!(locations instanceof String)) {
                 return -FAR_AWAY;
             }
-            String loc = ((String)locations).replace(" ", "");
-            String[] split = loc.split(",");
+            final String loc = ((String) locations).replace(" ", "");
+            final String[] split = loc.split(",");
             if (split.length < 1) {
                 return -FAR_AWAY;
             }
             try {
                 double min = Double.parseDouble(split[0]);
                 for (int i = 1; i < split.length; ++i) {
-                    double v = Double.parseDouble(split[i]);
+                    final double v = Double.parseDouble(split[i]);
                     if (v < min) {
                         min = v;
                     }
                 }
                 return min;
             }
-            catch (NumberFormatException nfe) {
+            catch (final NumberFormatException nfe) {
                 return -FAR_AWAY;
             }
-        }
-        else {
+        } else {
             if (!(from instanceof String)) {
                 return -FAR_AWAY;
             }
-            String f = (String)from;
+            final String f = (String) from;
             try {
                 return Double.parseDouble(f);
             }
-            catch(NumberFormatException nfe) {
+            catch (final NumberFormatException nfe) {
                 return -FAR_AWAY;
             }
         }
     }
 
-    /** Implementation for getting the maximum value of location or distance
-     *  dc:toValue.
+    /**
+     * Implementation for getting the maximum value of location or distance
+     * dc:toValue.
      */
-    public static Object toValue(List args) throws XPathFunctionException {
-        Object mode      = args.get(0);
-        Object locations = args.get(1);
-        Object to        = args.get(2);
+    public static Object toValue(final List args) throws XPathFunctionException {
+        final Object mode = args.get(0);
+        final Object locations = args.get(1);
+        final Object to = args.get(2);
 
-        if ((mode instanceof String && mode.equals("location")) ||
-            (locations instanceof String && !((String)locations).isEmpty())) {
+        if ((mode instanceof String && mode.equals("location")) || (locations instanceof String && !((String) locations).isEmpty())) {
             if (!(locations instanceof String)) {
                 return FAR_AWAY;
             }
             try {
-                String loc = ((String)locations).replace(" ", "");
-                String[] split = loc.split(",");
+                final String loc = ((String) locations).replace(" ", "");
+                final String[] split = loc.split(",");
                 if (split.length < 1) {
                     return FAR_AWAY;
                 }
                 double max = Double.parseDouble(split[0]);
                 for (int i = 1; i < split.length; ++i) {
-                    double v = Double.parseDouble(split[i]);
+                    final double v = Double.parseDouble(split[i]);
                     if (v > max) {
                         max = v;
                     }
                 }
                 return max;
             }
-            catch (NumberFormatException nfe) {
+            catch (final NumberFormatException nfe) {
                 return FAR_AWAY;
             }
-        }
-        else {
+        } else {
             if (!(to instanceof String)) {
                 return FAR_AWAY;
-            }
-            else {
-                String t = (String)to;
+            } else {
+                final String t = (String) to;
                 try {
                     return Double.parseDouble(t);
                 }
-                catch (NumberFormatException nfe) {
+                catch (final NumberFormatException nfe) {
                     return FAR_AWAY;
                 }
             }
         }
     }
 
-    /** Implementation for doing a string replace
-     *  dc:replace .
+    /**
+     * Implementation for doing a string replace
+     * dc:replace .
      */
-    public static Object replace(List args) throws XPathFunctionException {
-        Object haystack    = args.get(0);
-        Object needle      = args.get(1);
-        Object replacement = args.get(2);
+    public static Object replace(final List args) throws XPathFunctionException {
+        final Object haystack = args.get(0);
+        final Object needle = args.get(1);
+        final Object replacement = args.get(2);
 
-        if (needle      instanceof String
-        &&  haystack    instanceof String
-        &&  replacement instanceof String) {
-            return ((String)haystack).replace(
-                    (String)needle, (String)replacement);
+        if (needle instanceof String && haystack instanceof String && replacement instanceof String) {
+            return ((String) haystack).replace((String) needle, (String) replacement);
         }
         return haystack;
     }
 
-    /** Implementation for doing a string replace
-     *  dc:replace-all
+    /**
+     * Implementation for doing a string replace
+     * dc:replace-all
      */
-    public static Object replaceAll(List args) throws XPathFunctionException {
-        Object haystack    = args.get(0);
-        Object needle      = args.get(1);
-        Object replacement = args.get(2);
+    public static Object replaceAll(final List args) throws XPathFunctionException {
+        final Object haystack = args.get(0);
+        final Object needle = args.get(1);
+        final Object replacement = args.get(2);
 
-        if (needle      instanceof String
-        &&  haystack    instanceof String
-        &&  replacement instanceof String) {
-            return ((String)haystack).replaceAll(
-                    (String)needle, (String)replacement);
+        if (needle instanceof String && haystack instanceof String && replacement instanceof String) {
+            return ((String) haystack).replaceAll((String) needle, (String) replacement);
         }
         return haystack;
     }
 
-    public static Object dateFormat(List args) throws XPathFunctionException {
-        Object pattern = args.get(0);
-        Object date    = args.get(1);
+    public static Object dateFormat(final List args) throws XPathFunctionException {
+        final Object pattern = args.get(0);
+        Object date = args.get(1);
 
         try {
             // TODO: Take locale into account.
-            SimpleDateFormat format = new SimpleDateFormat((String)pattern);
+            final SimpleDateFormat format = new SimpleDateFormat((String) pattern);
 
             if (date instanceof Number) {
-                return format.format(new Date(((Number)date).longValue()));
+                return format.format(new Date(((Number) date).longValue()));
             }
 
             try {
-                /* Oracle does not return a date object but
-                   an oracle.sql.TIMESTAMP */
-                Method meth = date.getClass()
-                    .getMethod("dateValue", new Class[] {});
+                /*
+                 * Oracle does not return a date object but
+                 * an oracle.sql.TIMESTAMP
+                 */
+                final Method meth = date.getClass().getMethod("dateValue", new Class[] {});
                 date = meth.invoke(date, new Object[] {});
-            } catch (IllegalArgumentException e) {
-            } catch (IllegalAccessException e) {
-            } catch (InvocationTargetException e) {
-            } catch (NoSuchMethodException e) {
+            }
+            catch (final IllegalArgumentException e) {
+            }
+            catch (final IllegalAccessException e) {
+            }
+            catch (final InvocationTargetException e) {
+            }
+            catch (final NoSuchMethodException e) {
             }
 
             if (date instanceof Date) {
-                return format.format((Date)date);
+                return format.format((Date) date);
             }
         }
-        catch (IllegalArgumentException iae) {
+        catch (final IllegalArgumentException iae) {
             log.error(iae.getMessage());
         }
 
         return "";
     }
 
-    public static Set<String> allStateSuccessors(
-        String artifactName,
-        String stateId
-    ) {
-        GlobalContext gc = RiverContextFactory.getGlobalContext();
+    public static Set<String> allStateSuccessors(final String artifactName, final String stateId) {
+        final GlobalContext gc = RiverContextFactory.getGlobalContext();
         if (gc == null) {
             return Collections.<String>emptySet();
         }
-        Object o = gc.get(RiverContext.TRANSITION_ENGINE_KEY);
+        final Object o = gc.get(RiverContext.TRANSITION_ENGINE_KEY);
         if (o instanceof TransitionEngine) {
-            TransitionEngine te = (TransitionEngine)o;
+            final TransitionEngine te = (TransitionEngine) o;
             return te.allRecursiveSuccessorStateIds(artifactName, stateId);
         }
         return Collections.<String>emptySet();
     }
 
-    public static Collection<String> findAll(String needle, String haystack) {
+    public static Collection<String> findAll(final String needle, final String haystack) {
 
-        ArrayList<String> result = new ArrayList<String>();
+        final ArrayList<String> result = new ArrayList<>();
 
-        Pattern pattern = Pattern.compile(needle);
-        Matcher matcher = pattern.matcher(haystack);
+        final Pattern pattern = Pattern.compile(needle);
+        final Matcher matcher = pattern.matcher(haystack);
         while (matcher.find()) {
             result.add(matcher.group());
         }
         return result;
     }
 
-    public static Number maxNumber(Object list) {
+    public static Number maxNumber(final Object list) {
         if (list instanceof Collection) {
-            Collection collection = (Collection)list;
+            final Collection collection = (Collection) list;
             double max = -Double.MAX_VALUE;
-            for (Object x: collection) {
+            for (final Object x : collection) {
                 Number n;
                 if (x instanceof Number) {
-                    n = (Number)x;
-                }
-                else if (x instanceof String) {
+                    n = (Number) x;
+                } else if (x instanceof String) {
                     try {
-                        n = Double.valueOf((String)x);
+                        n = Double.valueOf((String) x);
                     }
-                    catch (NumberFormatException nfe) {
+                    catch (final NumberFormatException nfe) {
                         log.warn("'" + x + "' is not a number.");
                         continue;
                     }
-                }
-                else {
+                } else {
                     log.warn("'" + x + "' is not a number.");
                     continue;
                 }
 
-                double v = n.doubleValue();
+                final double v = n.doubleValue();
 
                 if (v > max) {
                     max = v;
                 }
             }
 
-            return Double.valueOf(max == -Double.MAX_VALUE
-                ? Double.MAX_VALUE
-                : max);
+            return Double.valueOf(max == -Double.MAX_VALUE ? Double.MAX_VALUE : max);
         }
 
-        return list instanceof Number
-            ? (Number)list
-            : Double.valueOf(Double.MAX_VALUE);
+        return list instanceof Number ? (Number) list : Double.valueOf(Double.MAX_VALUE);
     }
 
-    public static Number minNumber(Object list) {
+    public static Number minNumber(final Object list) {
         if (list instanceof Collection) {
-            Collection collection = (Collection)list;
+            final Collection collection = (Collection) list;
             double min = Double.MAX_VALUE;
-            for (Object x: collection) {
+            for (final Object x : collection) {
                 Number n;
                 if (x instanceof Number) {
-                    n = (Number)x;
-                }
-                else if (x instanceof String) {
+                    n = (Number) x;
+                } else if (x instanceof String) {
                     try {
-                        n = Double.valueOf((String)x);
+                        n = Double.valueOf((String) x);
                     }
-                    catch (NumberFormatException nfe) {
+                    catch (final NumberFormatException nfe) {
                         log.warn("'" + x + "' is not a number.");
                         continue;
                     }
-                }
-                else {
+                } else {
                     log.warn("'" + x + "' is not a number.");
                     continue;
                 }
 
-                double v = n.doubleValue();
+                final double v = n.doubleValue();
 
                 if (v < min) {
                     min = v;
                 }
             }
 
-            return Double.valueOf(min == Double.MAX_VALUE
-                ? -Double.MAX_VALUE
-                : min);
+            return Double.valueOf(min == Double.MAX_VALUE ? -Double.MAX_VALUE : min);
         }
 
-        return list instanceof Number
-            ? (Number)list
-            : Double.valueOf(-Double.MAX_VALUE);
+        return list instanceof Number ? (Number) list : Double.valueOf(-Double.MAX_VALUE);
     }
 
-    public static Object coalesce(List list) {
-        for (Object x: list) {
-            if (x instanceof String && ((String)x).length() != 0) {
+    public static Object coalesce(final List list) {
+        for (final Object x : list) {
+            if (x instanceof String && ((String) x).length() != 0) {
                 return x;
             }
-            if (x instanceof Number && ((Number)x).doubleValue() != 0.0) {
+            if (x instanceof Number && ((Number) x).doubleValue() != 0.0) {
                 return x;
             }
         }
         return StackFrames.NULL;
     }
 
-    private Object column(Object argument) {
-        
-        if( !(argument instanceof String) )
+    private Object column(final Object argument) {
+
+        if (!(argument instanceof String))
             throw new IllegalArgumentException("Argument of 'column' function must be a string");
-        
-        String columnName = (String) argument;
 
-        StackFrames frms = buildHelper.frames;
-        
+        final String columnName = (String) argument;
+
+        final StackFrames frms = this.buildHelper.frames;
+
         return frms.getNull(columnName);
     }
 }
--- a/artifacts/src/main/java/org/dive4elements/river/exports/WstWriter.java	Wed Jul 25 11:33:48 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/WstWriter.java	Wed Jul 25 14:42:44 2018 +0200
@@ -12,7 +12,6 @@
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
-
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
@@ -21,12 +20,10 @@
 import java.util.Map;
 import java.util.TreeMap;
 
-import org.apache.log4j.Logger;
 import org.apache.commons.lang.StringUtils;
-
+import org.apache.log4j.Logger;
 import org.dive4elements.river.artifacts.model.WstLine;
 
-
 /**
  * A writer that creates WSTs.
  *
@@ -49,7 +46,7 @@
     private static Logger log = Logger.getLogger(WstWriter.class);
 
     /** The default unit that is written into the header of the WST. */
-    public static final String DEFAULT_UNIT = "Wassserstand [NN + m]";
+    public static final String DEFAULT_UNIT = "Wasserstand [NN + m]";
 
     /** The lines that need to be included for the export. */
     protected Map<Double, WstLine> lines;
@@ -66,54 +63,58 @@
     /** The last Q values. */
     protected double[] qs;
 
-    /** Workaround for one use of wrongly imported files: ignore the Qs at
-     * all. */
+    /**
+     * Workaround for one use of wrongly imported files: ignore the Qs at
+     * all.
+     */
     protected boolean ignoreQs;
 
     /**
      * This constructor creates a new WstWriter with a number of Q columns.
      *
-     * @param columns The number of columns of the resulting WST.
+     * @param columns
+     *            The number of columns of the resulting WST.
      */
-    public WstWriter(int columns) {
+    public WstWriter(final int columns) {
         this(columns, false);
     }
 
     /**
      * This constructor creates a new WstWriter with a number of Q columns.
      *
-     * @param columns The number of columns of the resulting WST.
-     * @param workaroundIgnoreQs do not write QLines to shadow broken data.
+     * @param columns
+     *            The number of columns of the resulting WST.
+     * @param workaroundIgnoreQs
+     *            do not write QLines to shadow broken data.
      */
-    public WstWriter(int columns, boolean workaroundIgnoreQs) {
-        this.cols        = columns;
-        this.columnNames = new ArrayList<String>(cols);
-        this.lines       = new HashMap<Double, WstLine>();
-        this.qs          = new double[cols];
-        this.locale      = Locale.US;
-        this.ignoreQs    = workaroundIgnoreQs;
+    public WstWriter(final int columns, final boolean workaroundIgnoreQs) {
+        this.cols = columns;
+        this.columnNames = new ArrayList<>(this.cols);
+        this.lines = new HashMap<>();
+        this.qs = new double[this.cols];
+        this.locale = Locale.US;
+        this.ignoreQs = workaroundIgnoreQs;
     }
 
-
     /**
      * This method is used to create the WST from the data that has been
      * inserted using add(double[]) before.
-     * @param out Where to write to.
+     * 
+     * @param out
+     *            Where to write to.
      */
-    public void write(OutputStream out) {
+    public void write(final OutputStream out) {
         log.info("WstWriter.write");
 
-        PrintWriter writer = new PrintWriter(
-            new BufferedWriter(
-                new OutputStreamWriter(out)));
+        final PrintWriter writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(out)));
 
-        this.qs = new double[cols];
+        this.qs = new double[this.cols];
 
         writeHeader(writer);
 
-        Collection<WstLine> collection = new TreeMap(lines).values();
+        final Collection<WstLine> collection = new TreeMap(this.lines).values();
 
-        for (WstLine line: collection) {
+        for (final WstLine line : collection) {
             writeWLine(writer, line);
         }
 
@@ -121,75 +122,74 @@
         writer.close();
     }
 
-
     /**
      * This method is used to add a new line to the WST.
      *
-     * @param wqkms A 3dim double array with [W, Q, KM].
+     * @param wqkms
+     *            A 3dim double array with [W, Q, KM].
      */
-    public void add(double[] wqkms) {
-        Double km = wqkms[2];
+    public void add(final double[] wqkms) {
+        final Double km = wqkms[2];
 
-        WstLine line = lines.get(km);
+        WstLine line = this.lines.get(km);
 
         if (line == null) {
             line = new WstLine(km.doubleValue());
-            lines.put(km, line);
+            this.lines.put(km, line);
         }
 
         line.add(wqkms[0], wqkms[1]);
     }
 
+    public void addCorrected(final double[] wqckms) {
+        final Double km = wqckms[2];
 
-    public void addCorrected(double[] wqckms) {
-        Double km = wqckms[2];
-
-        WstLine line = lines.get(km);
+        WstLine line = this.lines.get(km);
 
         if (line == null) {
             line = new WstLine(km.doubleValue());
-            lines.put(km, line);
+            this.lines.put(km, line);
         }
 
         line.add(wqckms[3], wqckms[1]);
     }
 
-
     /**
      * Adds a further column name.
      *
-     * @param name The name of the new column.
+     * @param name
+     *            The name of the new column.
      */
     public void addColumn(String name) {
         if (name != null) {
-            cols++;
+            this.cols++;
 
             int i = 0;
-            String basename = name;
-            while (columnNames.contains(name)) {
+            final String basename = name;
+            while (this.columnNames.contains(name)) {
                 name = basename + "_" + i++;
             }
 
-            columnNames.add(name);
+            this.columnNames.add(name);
         }
     }
 
-
     /**
      * This method writes the header of the WST.
      *
-     * @param writer The PrintWriter that creates the output.
+     * @param writer
+     *            The PrintWriter that creates the output.
      */
-    protected void writeHeader(PrintWriter writer) {
+    protected void writeHeader(final PrintWriter writer) {
         log.debug("WstWriter.writeHeader");
 
-        writer.println(cols);
+        writer.println(this.cols);
 
         writer.print("*!column-bez-text ");
 
-        List<String> quotedNames = new ArrayList<String>(columnNames.size());
+        final List<String> quotedNames = new ArrayList<>(this.columnNames.size());
 
-        for (String name: columnNames) {
+        for (String name : this.columnNames) {
             if (name.contains(" ")) {
                 name = '"' + name + '"';
             }
@@ -198,12 +198,11 @@
         writer.println(StringUtils.join(quotedNames, " "));
         writer.print("        ");
 
-        for (String columnName: columnNames) {
+        for (final String columnName : this.columnNames) {
             if (columnName.length() > 9) {
-                writer.printf(locale, "%9s",
-                        columnName.substring(columnName.length() - 9));
+                writer.printf(this.locale, "%9s", columnName.substring(columnName.length() - 9));
             } else {
-                writer.printf(locale, "%9s", columnName);
+                writer.printf(this.locale, "%9s", columnName);
                 // This is weird but i was to lazy to lookup
                 // how to do this another way.
                 for (int i = 9 - columnName.length(); i > 0; i--) {
@@ -219,62 +218,63 @@
         writer.println();
     }
 
-
     /**
      * This method writes a line with W values and a certain kilometer.
      *
-     * @param writer The PrintWriter that is used to create the output.
-     * @param line The WstLine that should be written to the output.
+     * @param writer
+     *            The PrintWriter that is used to create the output.
+     * @param line
+     *            The WstLine that should be written to the output.
      */
-    protected void writeWLine(PrintWriter writer, WstLine line) {
-        double   km  = line.getKm();
-        double[] qs  = line.getQs();
-        int      num = line.getSize();
+    protected void writeWLine(final PrintWriter writer, final WstLine line) {
+        final double km = line.getKm();
+        final double[] qs = line.getQs();
+        final int num = line.getSize();
 
-        if (!ignoreQs && dischargesChanged(qs)) {
+        if (!this.ignoreQs && dischargesChanged(qs)) {
             writeQLine(writer, qs);
         }
 
-        writer.printf(locale, "%8.3f", km);
+        writer.printf(this.locale, "%8.3f", km);
 
         for (int i = 0; i < num; i++) {
-            writer.printf(locale, "%9.2f", line.getW(i));
+            writer.printf(this.locale, "%9.2f", line.getW(i));
         }
 
         writer.println();
     }
 
-
     /**
      * Writes a discharge line (Q values) into a WST.
      *
-     * @param qs the Q values for the next range.
+     * @param qs
+     *            the Q values for the next range.
      */
-    protected void writeQLine(PrintWriter writer, double[] qs) {
+    protected void writeQLine(final PrintWriter writer, final double[] qs) {
         writer.write("*\u001f      ");
 
         for (int i = 0; i < qs.length; i++) {
             this.qs[i] = qs[i];
 
-            writer.printf(locale, "%9.2f", qs[i]);
+            writer.printf(this.locale, "%9.2f", qs[i]);
         }
 
         writer.println();
     }
 
-
     /**
      * This method determines if a Q has changed from the last line to the
      * current one.
      *
-     * @param newQs The Q values of the next line.
+     * @param newQs
+     *            The Q values of the next line.
      *
      * @return true, if a Q value have changed, otherwise false.
      */
-    protected boolean dischargesChanged(double[] newQs) {
+    protected boolean dischargesChanged(final double[] newQs) {
         // XXX maybe there is a way to do this faster
-        for (int i = 0; i < cols && i < qs.length && i < newQs.length; i++) {
-            if (Math.abs(newQs[i] - qs[i]) >= 0.001) {
+        for (int i = 0; i < this.cols && i < this.qs.length && i < newQs.length; i++) {
+            if (Math.abs(newQs[i] - this.qs[i]) >= 0.001) {
                 return true;
             }
         }
@@ -287,7 +287,7 @@
      * lines are a map with km as the key and a wstline as value.
      */
     public Map<Double, WstLine> getLines() {
-        return lines;
+        return this.lines;
     }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.java	Wed Jul 25 11:33:48 2018 +0200
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.java	Wed Jul 25 14:42:44 2018 +0200
@@ -1594,4 +1594,8 @@
     String bundu_bezugswst_validation_range();
 
     String missingInputs();
+
+    String defaultVegetationZone();
+
+    String uinfo_inundation_duration_set_vegetation_zone();
 }
\ No newline at end of file
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.properties	Wed Jul 25 11:33:48 2018 +0200
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.properties	Wed Jul 25 14:42:44 2018 +0200
@@ -825,8 +825,10 @@
 uinfo = U-INFO
 uinfo_salix_dmwspl_short = \u0394MW [cm]
 uinfo_inundation_duration_export = \u00dcberflutungsdauern Export
+uinfo_inundation_duration_set_vegetation_zone = Vegetationstabelle \u00fcbernehmen
 uinfo_salix_line_export = Salix-Linie Export
 uinfo_vegetation_zones_export = Vegetationszonen Export
+defaultVegetationZone = Standardvegetationszone
 
 uinfo_vegetation_zone_overlap = Bereiche \u00fcberlappen.
 uinfo_vegetation_zone_has_gaps =  Die Wertebelegung (0-365) weist L\u00fccken auf.
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants_de.properties	Wed Jul 25 11:33:48 2018 +0200
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants_de.properties	Wed Jul 25 14:42:44 2018 +0200
@@ -825,8 +825,10 @@
 uinfo = U-INFO
 uinfo_salix_dmwspl_short = \u0394MW [cm]
 uinfo_inundation_duration_export = \u00dcberflutungsdauern Export
+uinfo_inundation_duration_set_vegetation_zone = Vegetationstabelle \u00fcbernehmen
 uinfo_salix_line_export = Salix-Linie Export
 uinfo_vegetation_zones_export = Vegetationszonen Export
+defaultVegetationZone = Standardvegetationszone
 
 uinfo_vegetation_zone_overlap = Bereiche \u00fcberlappen.
 uinfo_vegetation_zone_has_gaps = Die Wertebelegung (0-365) weist L\u00fccken auf.
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/UIProviderFactory.java	Wed Jul 25 11:33:48 2018 +0200
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/UIProviderFactory.java	Wed Jul 25 14:42:44 2018 +0200
@@ -99,7 +99,7 @@
         } else if (uiProvider.equals("uinfo.vegetationzones.table.edit")) {
             return new VegetationzonesTableEditPanel();
         } else if (uiProvider.equals("uinfo.vegetationzones.table")) {
-            return new VegetationzonesTablePanel();
+            return new VegetationzonesTablePanel(user);
         } else if (uiProvider.equals("wsp_datacage_panel")) {
             return new WspDatacagePanel(user);
         } else if (uiProvider.equals("dgm_datacage_panel")) {
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/uinfo/AbstractVegZonesTablePanel.java	Wed Jul 25 11:33:48 2018 +0200
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/uinfo/AbstractVegZonesTablePanel.java	Wed Jul 25 14:42:44 2018 +0200
@@ -108,7 +108,7 @@
         fromField.addCellSavedHandler(new CellSavedHandler() {
             @Override
             public void onCellSaved(final CellSavedEvent event) {
-                validateRangeOverlap();
+                updateValidationMsgLabel();
             }
         });
         // war mal ne anforderung, dass sich die Werte anderer Zellen ändern, sodass keine lücken entstehen... mach das jetzt
@@ -163,7 +163,7 @@
         toField.addCellSavedHandler(new CellSavedHandler() {
             @Override
             public void onCellSaved(final CellSavedEvent event) {
-                validateRangeOverlap();
+                updateValidationMsgLabel();
             }
         });
         // nicht
@@ -192,7 +192,7 @@
                 @Override
                 public void onRecordClick(final RecordClickEvent event) {
                     if (event.getField().getName().equals(removeField.getName())) {
-                        validateRangeOverlap();
+                        updateValidationMsgLabel();
                     }
                 }
             });
@@ -243,24 +243,31 @@
             if (dataItemContainer.getItems() != null) {
                 for (final DataItem dataItem : dataItemContainer.getItems()) {
                     if (dataItem.getStringValue() != null) {
-
-                        final List<VegetationZone> rows = VegetationZone.parse(dataItem.getStringValue());
-                        for (final VegetationZone row : rows) {
-                            this.elements.addData(createEntry(row));
-                        }
+                        createTableFromDataStr(dataItem.getStringValue());
                     }
                 }
             }
         }
     }
 
+    protected final void createTableFromDataStr(final String data) {
+        for (final ListGridRecord r : this.elements.getRecords()) {
+            this.elements.removeData(r);
+        }
+        final List<VegetationZone> rows = VegetationZone.parse(data);
+        for (final VegetationZone row : rows) {
+            this.elements.addData(createEntry(row));
+        }
+    }
+
     @Override
     public final Canvas create(final DataList data) {
         final VLayout layout = new VLayout();
 
         // TODO: Helper zur Vegetationszonen-Auswahl
-        // final Canvas helper = createHelper();
-        // this.helperContainer.addMember(helper);
+        final Canvas helper = createHelper(data);
+        if (helper != null)
+            this.helperContainer.addMember(helper);
 
         final Canvas submit = getNextButton();
 
@@ -271,7 +278,7 @@
         layout.addMember(root);
         layout.addMember(submit);
 
-        validateRangeOverlap();// init Text
+        updateValidationMsgLabel();// init Text
 
         return layout;
     }
@@ -351,7 +358,7 @@
 
     }
 
-    protected String validate(final String fromInput, final String toInput, final String zoneName, final String hexColor) {
+    protected final String validate(final String fromInput, final String toInput, final String zoneName, final String hexColor) {
 
         if (fromInput == null || toInput == null || zoneName == null || hexColor == null || fromInput.trim().isEmpty() || toInput.trim().isEmpty()
                 || zoneName.trim().isEmpty() || hexColor.trim().isEmpty())
@@ -378,7 +385,7 @@
     }
 
     @Override
-    public List<String> validate() {
+    public final List<String> validate() {
         final List<String> errors = new ArrayList<String>();
 
         if (VegetationZone.zonesAreOverlapping(this.getZones(this.elements.getRecords())))
@@ -388,7 +395,9 @@
         return errors;
     }
 
-    protected final void validateRangeOverlap() {
+    protected final void updateValidationMsgLabel() {
         this.validationLabel.setText(validate().toString().replace("[", "").replace("]", "").replace(",", ""));
     }
+
+    protected abstract Canvas createHelper(final DataList data);
 }
\ No newline at end of file
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/uinfo/VegetationzonesTableEditPanel.java	Wed Jul 25 11:33:48 2018 +0200
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/uinfo/VegetationzonesTableEditPanel.java	Wed Jul 25 14:42:44 2018 +0200
@@ -16,6 +16,7 @@
 import com.google.gwt.event.dom.client.ClickHandler;
 import com.google.gwt.user.client.ui.Button;
 import com.smartgwt.client.util.SC;
+import com.smartgwt.client.widgets.Canvas;
 import com.smartgwt.client.widgets.form.DynamicForm;
 import com.smartgwt.client.widgets.form.fields.ColorItem;
 import com.smartgwt.client.widgets.form.fields.TextItem;
@@ -82,7 +83,7 @@
                 r.setAttribute("to", v2);
                 r.setAttribute("color", v4);
                 elements.addData(r);
-                validateRangeOverlap();
+                updateValidationMsgLabel();
                 final String sortField = elements.getSortField();
                 if (sortField != null) {
                     elements.toggleSort(sortField);
@@ -92,11 +93,14 @@
         });
 
         fields.addMember(form1);
-
         root.addMember(fields);
         root.addMember(PanelHelper.getSpacer(10));
         root.addMember(add);
+    }
 
+    @Override
+    protected Canvas createHelper(final DataList data) {
+        return null;
     }
 
 }
\ No newline at end of file
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/uinfo/VegetationzonesTablePanel.java	Wed Jul 25 11:33:48 2018 +0200
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/uinfo/VegetationzonesTablePanel.java	Wed Jul 25 14:42:44 2018 +0200
@@ -8,13 +8,31 @@
 
 package org.dive4elements.river.client.client.ui.uinfo;
 
+import java.util.List;
+
+import org.dive4elements.river.client.client.ui.DatacageWidget;
+import org.dive4elements.river.client.client.ui.DatacageWidgetData;
 import org.dive4elements.river.client.shared.model.DataList;
+import org.dive4elements.river.client.shared.model.User;
 
+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.layout.Layout;
+import com.smartgwt.client.widgets.layout.VLayout;
+import com.smartgwt.client.widgets.tree.TreeNode;
 
 public class VegetationzonesTablePanel extends AbstractVegZonesTablePanel {
 
     private static final long serialVersionUID = 1L;
+    private final User user;
+
+    public VegetationzonesTablePanel(final User user) {
+        super();
+        this.user = user;
+    }
 
     @Override
     public void createWidget(final Layout root, final DataList data) {
@@ -23,4 +41,34 @@
 
         // fetchSedimentLoadData(); //TODO: feed from database...
     }
+
+    @Override
+    protected Canvas createHelper(final DataList dataList) {
+
+        final DatacageWidgetData data = new DatacageWidgetData(this.artifact, this.user, "uinfo.inundation_duration.vegZoneSelect", "load-system:true", false);
+
+        final DatacageWidget datacage = new DatacageWidget(data);
+
+        final Button plusBtn = new Button(this.MSG.uinfo_inundation_duration_set_vegetation_zone());
+        plusBtn.setAutoFit(true);
+        plusBtn.addClickHandler(new ClickHandler() {
+            @Override
+            public void onClick(final ClickEvent event) {
+                final List<TreeNode> selection = datacage.getPlainSelection();
+                if (selection == null || selection.isEmpty()) {
+                    SC.say(VegetationzonesTablePanel.this.MSG.warning());
+                    return;
+                }
+                final String data = selection.get(0).getAttribute("data");
+                createTableFromDataStr(data);
+                updateValidationMsgLabel();
+            }
+        });
+
+        final VLayout helperLayout = new VLayout();
+        helperLayout.addMember(datacage);
+        helperLayout.addMember(plusBtn);
+
+        return helperLayout;
+    }
 }
--- a/gwt-client/src/main/webapp/WEB-INF/web.xml	Wed Jul 25 11:33:48 2018 +0200
+++ b/gwt-client/src/main/webapp/WEB-INF/web.xml	Wed Jul 25 14:42:44 2018 +0200
@@ -205,6 +205,11 @@
   </servlet>
 
   <servlet>
+    <servlet-name>dynamicMainvalues</servlet-name>
+    <servlet-class>org.dive4elements.river.client.server.DynamicMainValuesServiceImpl</servlet-class>
+  </servlet>
+
+  <servlet>
     <servlet-name>gaugeinfo</servlet-name>
     <servlet-class>org.dive4elements.river.client.server.GaugeInfoServiceImpl</servlet-class>
   </servlet>
@@ -484,6 +489,11 @@
   </servlet-mapping>
 
   <servlet-mapping>
+    <servlet-name>dynamicMainvalues</servlet-name>
+    <url-pattern>/flys/dynamic-mainvalues</url-pattern>
+  </servlet-mapping>
+
+  <servlet-mapping>
     <servlet-name>gaugeinfo</servlet-name>
     <url-pattern>/flys/gaugeinfo</url-pattern>
   </servlet-mapping>

http://dive4elements.wald.intevation.org