changeset 9031:efd2de78d158

work on unit testing
author gernotbelger
date Fri, 27 Apr 2018 11:34:04 +0200
parents 4dc047fb3633
children 1f63e9d3b0ec
files gwt-client/src/main/java/org/dive4elements/river/client/test/ProofMain.java gwt-client/src/main/java/org/dive4elements/river/client/test/SinfoProof.java gwt-client/src/main/java/org/dive4elements/river/client/test/SuperProof.java gwt-client/src/test/java/org/dive4elements/river/client/FLYSJUnit.gwt.xml gwt-client/src/test/java/test/SinfoTest.java gwt-client/src/test/java/test/SuperTest.java gwt-client/src/test/java/test/TestMain.java gwt-client/src/test/resources/sinfo/flowdepthminmax/sinfo_flowdepthminmax_export.csv
diffstat 8 files changed, 630 insertions(+), 440 deletions(-) [+]
line wrap: on
line diff
--- a/gwt-client/src/main/java/org/dive4elements/river/client/test/ProofMain.java	Fri Apr 27 10:48:28 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2010 by Intevation GmbH
- *
- * This program is free software under the LGPL (>=v2.1)
- * Read the file LGPL.txt coming with the software for details
- * or visit http://www.gnu.org/licenses/ if it does not exist.
- */
-
-package org.dive4elements.river.client.test;
-
-import java.io.IOException;
-
-import org.dive4elements.artifacts.httpclient.http.HttpClient;
-import org.dive4elements.artifacts.httpclient.http.HttpClientImpl;
-import org.dive4elements.river.client.shared.exceptions.ServerException;
-
-/**
- * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
- */
-public class ProofMain {
-
-    private static final String serverUrl = "http://localhost:8181";
-    private static final String locale = "de";
-    private static final HttpClient client = new HttpClientImpl(serverUrl, locale);
-
-    public static void main(final String[] args) throws ServerException, IOException {
-        // logger.info("Starting console client.");
-        final SinfoProof proof = new SinfoProof("belger", "belger", "sinfo");
-        proof.runTest();
-    }
-
-}
--- a/gwt-client/src/main/java/org/dive4elements/river/client/test/SinfoProof.java	Fri Apr 27 10:48:28 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,87 +0,0 @@
-/** 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.test;
-
-import org.dive4elements.river.client.client.ui.NilDatacageTwinPanelInfo;
-import org.dive4elements.river.client.client.ui.RecommandationUtils;
-import org.dive4elements.river.client.shared.model.Artifact;
-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.DefaultDataItem;
-import org.dive4elements.river.client.shared.model.OutputMode;
-import org.dive4elements.river.client.shared.model.Recommendation;
-import org.dive4elements.river.client.shared.model.StringOptionsData;
-
-/**
- * @author Domenico Nardi Tironi
- *
- */
-public class SinfoProof extends SuperProof {
-
-    public SinfoProof(final String username, final String password, final String infotype) {
-        super(username, password, infotype);
-
-    }
-
-    @Override
-    public void runTest() {
-        // TODO Auto-generated method stub
-        /* Select River */
-        final Data data = new StringOptionsData("river", "river", new DataItem[] { new DefaultDataItem("Beispielfluss", "Beispielfluss", "Beispielfluss") });
-        feedAndGo(new Data[] { data }, 0);
-
-        /* Select CalcMode */
-        final DataList calcModes = getArtifact().getArtifactDescription().getCurrentData(); // AUSWAHL-Möglichkeiten
-        final DataItem minMaxFlowdepth = calcModes.get(0).getItems()[2];
-        final Data dataCalcMode = new StringOptionsData("calculation_mode", "calculation_mode", new DataItem[] { minMaxFlowdepth });
-        feedAndGo(new Data[] { dataCalcMode }, 0);
-
-        /* Select Range */
-
-        // entweder eine bestimmte Range
-        final Data dataFrom = new StringOptionsData("ld_from", "ld_from", new DataItem[] { new DefaultDataItem("10", "10", "10") });
-        final Data dataTo = new StringOptionsData("ld_to", "ld_to", new DataItem[] { new DefaultDataItem("100", "100", "100") });
-        final Data[] rangeFromToDetermined = new Data[] { dataFrom, dataTo };
-
-        // oder die maxRange
-        final DataList list = getArtifact().getArtifactDescription().getCurrentData();
-        final Data[] rangeMax = new Data[] { list.get(0), list.get(1) };
-
-        feedAndGo(rangeFromToDetermined, 0);
-
-        /* Select Fixpunkte */
-        // TODO: Create Recoomendation-Generator
-        final Recommendation rec1 = new Recommendation("staticwqkms", "additionals-wstv-0-103", "sinfo_flowdepth_waterlevels");
-        final Recommendation rec2 = new Recommendation("bedheight", "bedheight-single-36-2015-FP-2015_0-502", "sinfo_flowdepthminmax_heights");
-
-        final Artifact[] artifacts = loadMany(new Recommendation[] { rec1, rec2 }, null);
-
-        // rec1.getDisplayName() TODO: makeDisplayName
-        final String rec1String = RecommandationUtils.createDataString(artifacts[0].getUuid(), rec1, new NilDatacageTwinPanelInfo("xxxx"));
-        final String rec2String = RecommandationUtils.createDataString(artifacts[1].getUuid(), rec2, new NilDatacageTwinPanelInfo("xxxx"));
-        // TODO: check display name
-        final String combinedIdNeu = rec1String + "#" + rec2String;
-
-        final Data pair = new StringOptionsData("diffids", "diffids", new DataItem[] { new DefaultDataItem(combinedIdNeu, combinedIdNeu, combinedIdNeu) });
-        feedAndGo(new Data[] { pair }, 0);
-
-        // Describe collection
-        describeCollection(); // wichtig, damit die Facets erzeugt werden
-
-        // /* Export calculation */
-        final OutputMode[] modes = getArtifact().getArtifactDescription().getOutputModes();
-        if (modes != null) {
-            final OutputMode mode = modes[1]; // output.sinfo_flowdepthminmax_export
-            doGet(mode.getName());
-        }
-    }
-
-}
--- a/gwt-client/src/main/java/org/dive4elements/river/client/test/SuperProof.java	Fri Apr 27 10:48:28 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,310 +0,0 @@
-/** 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.test;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.util.ArrayList;
-import java.util.HashMap;
-
-import org.dive4elements.artifacts.common.ArtifactNamespaceContext;
-import org.dive4elements.artifacts.common.utils.ClientProtocolUtils;
-import org.dive4elements.artifacts.httpclient.exceptions.ConnectionException;
-import org.dive4elements.artifacts.httpclient.http.HttpClient;
-import org.dive4elements.artifacts.httpclient.http.HttpClientImpl;
-import org.dive4elements.artifacts.httpclient.http.response.DocumentResponseHandler;
-import org.dive4elements.artifacts.httpclient.utils.XMLUtils;
-import org.dive4elements.river.client.server.AdvanceServiceImpl;
-import org.dive4elements.river.client.server.ArtifactHelper;
-import org.dive4elements.river.client.server.CollectionHelper;
-import org.dive4elements.river.client.server.CreateCollectionServiceImpl;
-import org.dive4elements.river.client.server.FLYSArtifactCreator;
-import org.dive4elements.river.client.server.FeedServiceImpl;
-import org.dive4elements.river.client.server.LoadArtifactServiceImpl;
-import org.dive4elements.river.client.server.auth.DefaultUser;
-import org.dive4elements.river.client.server.auth.User;
-import org.dive4elements.river.client.server.auth.UserClient;
-import org.dive4elements.river.client.shared.exceptions.ServerException;
-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.DefaultCollection;
-import org.dive4elements.river.client.shared.model.Recommendation;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-/**
- * @author Domenico Nardi Tironi
- *
- */
-public abstract class SuperProof {
-
-    private final String serverUrl = "http://localhost:8181";
-    private final String locale = "de";
-    private final HttpClient client;
-
-    private final String username;
-    private final String password;
-    private final String infotype;
-    private final String userUuid;
-    private Collection collection;
-    private Artifact artifact;
-
-    public SuperProof(final String username, final String password, final String infotype) {
-        this.username = username;
-        this.password = password;
-        this.infotype = infotype;
-
-        // init
-        this.client = new HttpClientImpl(this.serverUrl, this.locale);
-        this.userUuid = makeUserUuid();
-        this.collection = getCollection();
-        this.artifact = getArtifact();
-    }
-
-    private String makeUserUuid() {
-        final User user = new DefaultUser(this.username, this.password, null, false, new ArrayList<String>(), new ArrayList<String>());
-        final UserClient userClient = new UserClient(this.serverUrl);
-        Element userElement;
-        try {
-            userElement = userClient.findUser(user);
-            return userElement.getAttributeNS(ArtifactNamespaceContext.NAMESPACE_URI, "uuid");
-        }
-        catch (final ConnectionException e) {
-            e.printStackTrace();
-        }
-        return "";
-    }
-
-    protected final Artifact getArtifact() {
-
-        /* Init Collection */
-        if (this.artifact == null)
-            try {
-
-                this.artifact = ArtifactHelper.createArtifact(this.serverUrl, this.locale, this.infotype, null);
-                setCollection(CollectionHelper.addArtifact(getCollection(), this.artifact, this.serverUrl, this.locale)); // wichtig; sorgt für Persistenz
-            }
-            catch (final ServerException e) {
-                // TODO Auto-generated catch block
-                e.printStackTrace();
-            }
-        return this.artifact;
-    }
-
-    private Collection getCollection() {
-
-        if (this.collection == null) {
-            try {
-                // lazy-Loading
-                final Document create = ClientProtocolUtils.newCreateCollectionDocument(null);
-                final Document doc = (Document) this.client.createCollection(create, this.userUuid, new DocumentResponseHandler());
-                final String uuid = XMLUtils.xpathString(doc, CreateCollectionServiceImpl.XPATH_COLLECTION_UUID, ArtifactNamespaceContext.INSTANCE);
-                final String ttlStr = XMLUtils.xpathString(doc, CreateCollectionServiceImpl.XPATH_COLLECTION_TTL, ArtifactNamespaceContext.INSTANCE);
-                this.collection = new DefaultCollection(uuid, Long.valueOf(ttlStr), uuid);
-            }
-            catch (final ConnectionException e) {
-                // TODO Auto-generated catch block
-                e.printStackTrace();
-            }
-        }
-        return this.collection;
-    }
-
-    private void setCollection(final Collection collection) {
-        this.collection = collection;
-    }
-
-    private void setArtifact(final Artifact artifact) {
-        this.artifact = artifact;
-    }
-
-    // TODO: MAKE THIS CLASS ABSTRACT AND OVERRIDE runTest in children
-    public abstract void runTest();
-
-    protected final void describeCollection() {
-        try {
-            final String uuid = getCollection().identifier();
-            final Document describe = ClientProtocolUtils.newDescribeCollectionDocument(uuid);
-            final Document response = (Document) this.client.doCollectionAction(describe, uuid, new DocumentResponseHandler());
-            final Collection c = CollectionHelper.parseCollection(response);
-            setCollection(c);
-        }
-        catch (final ConnectionException e) {
-            e.printStackTrace();
-        }
-    }
-
-    protected final void feedAndGo(final Data[] data, final int reachableStateIndex) {
-        try {
-            feed(data);
-            advance(getReachableStateByIndex(getArtifact(), reachableStateIndex)); // reachablestate könnte auch String sein... TODO: feedAndgo(data,string)
-                                                                                   // bauen
-        }
-        catch (final ConnectionException e) {
-            e.printStackTrace();
-        }
-        catch (final ServerException e) {
-            e.printStackTrace();
-        }
-    }
-
-    private String getReachableStateByIndex(final Artifact artifact, final int index) {
-
-        final String[] states = artifact.getArtifactDescription().getReachableStates();
-        if (states != null) {
-            if (states.length > index) {
-                return states[index];
-            } else {
-                return states[0];
-            }
-        } else {
-            return "";
-        }
-    }
-
-    private void feed(final Data[] data) throws ServerException, ConnectionException {
-        final Document feed = ClientProtocolUtils.newFeedDocument(getArtifact().getUuid(), getArtifact().getHash(), createKVP(data));
-
-        final Document description = (Document) this.client.feed(
-                new org.dive4elements.artifacts.httpclient.objects.Artifact(getArtifact().getUuid(), getArtifact().getHash()), feed,
-                new DocumentResponseHandler());
-
-        final String result = XMLUtils.xpathString(description, FeedServiceImpl.XPATH_RESULT, ArtifactNamespaceContext.INSTANCE);
-
-        if (result == null || !result.equals(FeedServiceImpl.OPERATION_FAILURE)) {
-            setArtifact((Artifact) new FLYSArtifactCreator().create(description));
-        } else if (result != null && result.equals(FeedServiceImpl.OPERATION_FAILURE)) {
-            final String msg = XMLUtils.xpathString(description, FeedServiceImpl.XPATH_RESULT_MSG, ArtifactNamespaceContext.INSTANCE);
-            throw new ServerException(msg);
-        }
-
-        // throw new ServerException(FeedServiceImpl.ERROR_FEED_DATA);
-    }
-
-    private String[][] createKVP(final Data[] data) {
-        if (data != null) {
-            final String[][] kvp = new String[data.length][];
-
-            int i = 0;
-
-            for (final Data d : data) {
-                // final DataItem[] items = d.getItems();
-                final String key = d.getLabel();
-                final String value = d.getStringValue();
-
-                kvp[i++] = new String[] { key, value };
-            }
-
-            return kvp;
-        }
-        return null;
-    }
-
-    private void advance(final String target) throws ConnectionException, ServerException {
-        final Document advance = ClientProtocolUtils.newAdvanceDocument(getArtifact().getUuid(), getArtifact().getHash(), target);
-        // final HttpClient client = new HttpClientImpl(url, locale);
-
-        final Document description = (Document) this.client.advance(
-                new org.dive4elements.artifacts.httpclient.objects.Artifact(getArtifact().getUuid(), getArtifact().getHash()), advance,
-                new DocumentResponseHandler());
-
-        if (description == null) {
-            throw new ServerException(AdvanceServiceImpl.ERROR_ADVANCE_ARTIFACT);
-        }
-
-        final String result = XMLUtils.xpathString(description, AdvanceServiceImpl.XPATH_RESULT, ArtifactNamespaceContext.INSTANCE);
-
-        if (result == null || !result.equals(AdvanceServiceImpl.OPERATION_FAILURE)) {
-            setArtifact((Artifact) new FLYSArtifactCreator().create(description));
-        }
-
-        // throw new ServerException(AdvanceServiceImpl.ERROR_ADVANCE_ARTIFACT);
-    }
-
-    protected final Artifact[] loadMany(final Recommendation[] recoms, final String factory) {
-        try {
-            final ArrayList<Artifact> artifacts = new ArrayList<Artifact>();
-            final HashMap<Recommendation, Artifact> cloneMap = new HashMap<Recommendation, Artifact>();
-
-            for (final Recommendation recom : recoms) {
-
-                final Artifact prevClone = cloneMap.get(recom);
-                if (prevClone != null) {
-
-                    artifacts.add(prevClone);
-                } else {
-                    // Not already cloned.
-                    final String realFactory = factory != null ? factory : recom.getFactory();
-
-                    final Artifact clone = ArtifactHelper.createArtifact(this.serverUrl, this.locale, realFactory, recom);
-
-                    if (clone != null) {
-                        final Collection c = CollectionHelper.addArtifact(getCollection(), clone, this.serverUrl, this.locale);
-
-                        if (c != null) {
-                            artifacts.add(clone);
-                            // Remember we cloned a recommendation like this.
-                            cloneMap.put(recom, clone);
-                        } else {
-                            throw new ServerException(LoadArtifactServiceImpl.ERROR_LOAD_ARTIFACT);
-                        }
-                    }
-                }
-            }
-            return artifacts.toArray(new Artifact[artifacts.size()]);
-        }
-        catch (final ServerException e) {
-            e.printStackTrace();
-        }
-        return null;
-    }
-
-    /// ExportServiceImpl
-    public void doGet(final String mode) {
-        try {
-
-            final String name = mode;
-            final String type = "csv";
-
-            final String fn = name + "." + type; // TODO: make filename unique
-            final String enc = "windows-1252";// req.getParameter("encoding");
-
-            final OutputStream out = new FileOutputStream(new File("D:" + File.separator + fn));
-            final Document attr = null;
-            final Document request = ClientProtocolUtils.newOutCollectionDocument(getCollection().identifier(), mode, type, attr);
-            // final HttpClient client = new HttpClientImpl(serverUrl, locale);
-
-            if (enc != null) {
-                final InputStreamReader in = new InputStreamReader(this.client.collectionOut(request, getCollection().identifier(), mode), "UTF-8");
-                try {
-                    final OutputStreamWriter encOut = new OutputStreamWriter(out, enc);
-                    final char buf[] = new char[4096];
-                    int c;
-                    while ((c = in.read(buf, 0, buf.length)) >= 0) {
-                        encOut.write(buf, 0, c);
-                    }
-                    encOut.flush();
-                    encOut.close();
-                } finally {
-                    in.close();
-                }
-            }
-        }
-        catch (final IOException ioe) {
-            ioe.printStackTrace();
-        }
-    }
-
-}
--- a/gwt-client/src/test/java/org/dive4elements/river/client/FLYSJUnit.gwt.xml	Fri Apr 27 10:48:28 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module>
-  <!-- Inherit our applications main module.                      -->
-  <inherits name='org.dive4elements.river.client.FLYS'/>
-
-  <!-- Specify the path to any remote services.                   -->
-  <!--
-  <servlet path="/flys/greet" class="org.dive4elements.river.client.server.GreetingServiceImpl" />
-  -->
-
-</module>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gwt-client/src/test/java/test/SinfoTest.java	Fri Apr 27 11:34:04 2018 +0200
@@ -0,0 +1,77 @@
+package test;
+
+/** 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.
+ */
+
+import java.io.IOException;
+
+import org.dive4elements.artifacts.httpclient.exceptions.ConnectionException;
+import org.dive4elements.river.client.shared.exceptions.ServerException;
+import org.dive4elements.river.client.shared.model.Data;
+import org.dive4elements.river.client.shared.model.DataItem;
+import org.dive4elements.river.client.shared.model.DefaultDataItem;
+import org.dive4elements.river.client.shared.model.OutputMode;
+import org.dive4elements.river.client.shared.model.StringOptionsData;
+
+/**
+ * @author Domenico Nardi Tironi
+ *
+ */
+public class SinfoTest extends SuperTest {
+
+    private final String calcMode;
+
+    public SinfoTest(final String username, final String password, final String infotype, final String calcmode) throws ConnectionException, ServerException {
+        super(username, password, infotype);
+        this.calcMode = calcmode;
+    }
+
+    @Override
+    public void runTest(final boolean exportToFile) throws ServerException, IOException {
+        // TODO Auto-generated method stub
+        /* Select River */
+        final Data data = new StringOptionsData("river", "river", new DataItem[] { new DefaultDataItem("Beispielfluss", "Beispielfluss", "Beispielfluss") });
+        feedAndGo(new Data[] { data }, 0);
+
+        /* Select CalcMode */
+        // final DataList calcModes = getArtifact().getArtifactDescription().getCurrentData(); // AUSWAHL-Möglichkeiten
+        // final DataItem minMaxFlowdepth = calcModes.get(0).getItems()[2]; // CalcMode
+        final Data dataCalcMode = new StringOptionsData("calculation_mode", "calculation_mode",
+                new DataItem[] { new DefaultDataItem(this.calcMode, this.calcMode, this.calcMode) });
+        feedAndGo(new Data[] { dataCalcMode }, 0);
+
+        /* Select Range */
+
+        // entweder eine bestimmte Range
+        final Data dataFrom = new StringOptionsData("ld_from", "ld_from", new DataItem[] { new DefaultDataItem("10", "10", "10") });
+        final Data dataTo = new StringOptionsData("ld_to", "ld_to", new DataItem[] { new DefaultDataItem("100", "100", "100") });
+        final Data[] rangeFromToDetermined = new Data[] { dataFrom, dataTo };
+
+        // oder die maxRange
+        // final DataList list = getArtifact().getArtifactDescription().getCurrentData();
+        // final Data[] rangeMax = new Data[] { list.get(0), list.get(1) };
+
+        feedAndGo(rangeFromToDetermined, 0);
+
+        /* Select Fixpunkte */
+        feedAndGo(super.getPairData(), 0);
+
+        // Describe collection
+        describeCollection(); // wichtig, damit die Facets erzeugt werden
+
+        // /* Export calculation */
+        final OutputMode[] modes = getArtifact().getArtifactDescription().getOutputModes();
+        if (modes != null) {
+            final OutputMode mode = modes[1]; // output.sinfo_flowdepthminmax_export
+            doGet(mode.getName(), exportToFile);
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gwt-client/src/test/java/test/SuperTest.java	Fri Apr 27 11:34:04 2018 +0200
@@ -0,0 +1,328 @@
+package test;
+
+/** 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.
+ */
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.dive4elements.artifacts.common.ArtifactNamespaceContext;
+import org.dive4elements.artifacts.common.utils.ClientProtocolUtils;
+import org.dive4elements.artifacts.httpclient.exceptions.ConnectionException;
+import org.dive4elements.artifacts.httpclient.http.HttpClient;
+import org.dive4elements.artifacts.httpclient.http.HttpClientImpl;
+import org.dive4elements.artifacts.httpclient.http.response.DocumentResponseHandler;
+import org.dive4elements.artifacts.httpclient.utils.XMLUtils;
+import org.dive4elements.river.client.client.ui.NilDatacageTwinPanelInfo;
+import org.dive4elements.river.client.client.ui.RecommandationUtils;
+import org.dive4elements.river.client.server.AdvanceServiceImpl;
+import org.dive4elements.river.client.server.ArtifactHelper;
+import org.dive4elements.river.client.server.CollectionHelper;
+import org.dive4elements.river.client.server.CreateCollectionServiceImpl;
+import org.dive4elements.river.client.server.FLYSArtifactCreator;
+import org.dive4elements.river.client.server.FeedServiceImpl;
+import org.dive4elements.river.client.server.LoadArtifactServiceImpl;
+import org.dive4elements.river.client.server.auth.DefaultUser;
+import org.dive4elements.river.client.server.auth.User;
+import org.dive4elements.river.client.server.auth.UserClient;
+import org.dive4elements.river.client.shared.exceptions.ServerException;
+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.DefaultCollection;
+import org.dive4elements.river.client.shared.model.DefaultDataItem;
+import org.dive4elements.river.client.shared.model.Recommendation;
+import org.dive4elements.river.client.shared.model.StringOptionsData;
+import org.junit.Assert;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * @author Domenico Nardi Tironi
+ *
+ */
+public abstract class SuperTest {
+
+    private final String serverUrl = "http://localhost:8181";
+    private final String locale = "de";
+    private final HttpClient client;
+
+    private static final String exportFileDir = "D:" + File.separator;
+    private static final String erstellDatumSearchString = "# Datum der Erstellung";
+
+    private final String username;
+    private final String password;
+    private final String infotype;
+    private final String userUuid;
+    private Collection collection;
+    private Artifact artifact;
+
+    private final List<String> pairIds = new ArrayList<String>();
+
+    public SuperTest(final String username, final String password, final String infotype) throws ConnectionException, ServerException {
+        this.username = username;
+        this.password = password;
+        this.infotype = infotype;
+
+        // init
+        this.client = new HttpClientImpl(this.serverUrl, this.locale);
+        this.userUuid = makeUserUuid();
+        this.collection = getCollection();
+        this.artifact = getArtifact();
+    }
+
+    private String makeUserUuid() throws ConnectionException {
+        final User user = new DefaultUser(this.username, this.password, null, false, new ArrayList<String>(), new ArrayList<String>());
+        final UserClient userClient = new UserClient(this.serverUrl);
+        Element userElement;
+
+        userElement = userClient.findUser(user);
+        return userElement.getAttributeNS(ArtifactNamespaceContext.NAMESPACE_URI, "uuid");
+
+    }
+
+    protected final Artifact getArtifact() throws ServerException, ConnectionException {
+        if (this.artifact == null) {
+            this.artifact = ArtifactHelper.createArtifact(this.serverUrl, this.locale, this.infotype, null);
+            setCollection(CollectionHelper.addArtifact(getCollection(), this.artifact, this.serverUrl, this.locale)); // wichtig; sorgt für Persistenz
+        }
+        return this.artifact;
+    }
+
+    private Collection getCollection() throws ConnectionException {
+
+        if (this.collection == null) {
+            // lazy-Loading
+            final Document create = ClientProtocolUtils.newCreateCollectionDocument(null);
+            final Document doc = (Document) this.client.createCollection(create, this.userUuid, new DocumentResponseHandler());
+            final String uuid = XMLUtils.xpathString(doc, CreateCollectionServiceImpl.XPATH_COLLECTION_UUID, ArtifactNamespaceContext.INSTANCE);
+            final String ttlStr = XMLUtils.xpathString(doc, CreateCollectionServiceImpl.XPATH_COLLECTION_TTL, ArtifactNamespaceContext.INSTANCE);
+            this.collection = new DefaultCollection(uuid, Long.valueOf(ttlStr), uuid);
+        }
+        return this.collection;
+
+    }
+
+    private void setCollection(final Collection collection) {
+        this.collection = collection;
+    }
+
+    private void setArtifact(final Artifact artifact) {
+        this.artifact = artifact;
+    }
+
+    public abstract void runTest(final boolean exportToFile) throws ConnectionException, ServerException, IOException;
+
+    protected final void describeCollection() throws ConnectionException {
+
+        final String uuid = getCollection().identifier();
+        final Document describe = ClientProtocolUtils.newDescribeCollectionDocument(uuid);
+        final Document response = (Document) this.client.doCollectionAction(describe, uuid, new DocumentResponseHandler());
+        final Collection c = CollectionHelper.parseCollection(response);
+        setCollection(c);
+
+    }
+
+    protected final void feedAndGo(final Data[] data, final int reachableStateIndex) throws ConnectionException, ServerException {
+        feed(data);
+        advance(getReachableStateByIndex(getArtifact(), reachableStateIndex)); // reachablestate könnte auch String sein... TODO: feedAndgo(data,string)
+                                                                               // bauen, falls irgendwann erforderlich
+    }
+
+    private String getReachableStateByIndex(final Artifact artifact, final int index) {
+
+        final String[] states = artifact.getArtifactDescription().getReachableStates();
+        if (states != null) {
+            if (states.length > index) {
+                return states[index];
+            } else {
+                return states[0];
+            }
+        } else {
+            return "";
+        }
+    }
+
+    private void feed(final Data[] data) throws ServerException, ConnectionException {
+        final Document feed = ClientProtocolUtils.newFeedDocument(getArtifact().getUuid(), getArtifact().getHash(), createKVP(data));
+        final Document description = (Document) this.client.feed(
+                new org.dive4elements.artifacts.httpclient.objects.Artifact(getArtifact().getUuid(), getArtifact().getHash()), feed,
+                new DocumentResponseHandler());
+
+        final String result = XMLUtils.xpathString(description, FeedServiceImpl.XPATH_RESULT, ArtifactNamespaceContext.INSTANCE);
+
+        if (result == null || !result.equals(FeedServiceImpl.OPERATION_FAILURE)) {
+            setArtifact((Artifact) new FLYSArtifactCreator().create(description));
+        } else if (result != null && result.equals(FeedServiceImpl.OPERATION_FAILURE)) {
+            final String msg = XMLUtils.xpathString(description, FeedServiceImpl.XPATH_RESULT_MSG, ArtifactNamespaceContext.INSTANCE);
+            throw new ServerException(msg);
+        }
+    }
+
+    private String[][] createKVP(final Data[] data) {
+        if (data != null) {
+            final String[][] kvp = new String[data.length][];
+
+            int i = 0;
+
+            for (final Data d : data) {
+                // final DataItem[] items = d.getItems();
+                final String key = d.getLabel();
+                final String value = d.getStringValue();
+
+                kvp[i++] = new String[] { key, value };
+            }
+
+            return kvp;
+        }
+        return null;
+    }
+
+    private void advance(final String target) throws ConnectionException, ServerException {
+        final Document advance = ClientProtocolUtils.newAdvanceDocument(getArtifact().getUuid(), getArtifact().getHash(), target);
+        final Document description = (Document) this.client.advance(
+                new org.dive4elements.artifacts.httpclient.objects.Artifact(getArtifact().getUuid(), getArtifact().getHash()), advance,
+                new DocumentResponseHandler());
+
+        if (description == null) {
+            throw new ServerException(AdvanceServiceImpl.ERROR_ADVANCE_ARTIFACT);
+        }
+
+        final String result = XMLUtils.xpathString(description, AdvanceServiceImpl.XPATH_RESULT, ArtifactNamespaceContext.INSTANCE);
+
+        if (result == null || !result.equals(AdvanceServiceImpl.OPERATION_FAILURE)) {
+            setArtifact((Artifact) new FLYSArtifactCreator().create(description));
+        }
+    }
+
+    protected final Artifact[] loadMany(final Recommendation[] recoms, final String factory) throws ServerException, ConnectionException {
+        final ArrayList<Artifact> artifacts = new ArrayList<Artifact>();
+        final HashMap<Recommendation, Artifact> cloneMap = new HashMap<Recommendation, Artifact>();
+
+        for (final Recommendation recom : recoms) {
+
+            final Artifact prevClone = cloneMap.get(recom);
+            if (prevClone != null) {
+
+                artifacts.add(prevClone);
+            } else {
+                // Not already cloned.
+                final String realFactory = factory != null ? factory : recom.getFactory();
+
+                final Artifact clone = ArtifactHelper.createArtifact(this.serverUrl, this.locale, realFactory, recom);
+
+                if (clone != null) {
+                    final Collection c = CollectionHelper.addArtifact(getCollection(), clone, this.serverUrl, this.locale);
+
+                    if (c != null) {
+                        artifacts.add(clone);
+                        // Remember we cloned a recommendation like this.
+                        cloneMap.put(recom, clone);
+                    } else {
+                        throw new ServerException(LoadArtifactServiceImpl.ERROR_LOAD_ARTIFACT);
+                    }
+                }
+            }
+        }
+        return artifacts.toArray(new Artifact[artifacts.size()]);
+
+    }
+
+    /// ExportServiceImpl
+    public void doGet(final String mode, final boolean exportToFile) throws IOException {
+
+        final String name = mode;
+        final String type = "csv";
+
+        final String fn = name + "." + type; // TODO: make filename unique
+        final String enc = "windows-1252";// req.getParameter("encoding");
+
+        final URL expectedResource = getClass().getResource("/sinfo/flowdepthminmax/" + fn);
+        final Document attr = null;
+        final Document request = ClientProtocolUtils.newOutCollectionDocument(getCollection().identifier(), mode, type, attr);
+
+        final InputStream response = this.client.collectionOut(request, getCollection().identifier(), mode);
+
+        final String actual = deleteErstelldatum(IOUtils.toString(response, "UTF-8"));
+
+        final String expected = deleteErstelldatum(FileUtils.readFileToString(new File(expectedResource.getFile()), enc));
+
+        // if (!actual.equals(expected)) {
+        if (exportToFile) {
+            doGetWriteToDisk(mode); // TODO: WENN der Test negativ ausfällt, Datei abspeichern -> Diskussion
+        }
+        Assert.assertEquals(actual, expected);
+
+    }
+
+    private String deleteErstelldatum(final String input) {
+        String result = "";
+        final String[] lines = input.split(System.lineSeparator());
+        for (final String line : lines) {
+            if (!line.contains(SuperTest.erstellDatumSearchString)) {
+                result = result + line + System.lineSeparator();
+            }
+        }
+        return result;
+    }
+
+    public void doGetWriteToDisk(final String mode) throws FileNotFoundException, IOException {
+
+        final String name = mode;
+        final String type = "csv";
+
+        final String fn = name + "." + type; // TODO: make filename unique
+        final String enc = "windows-1252";
+
+        final String filepath = exportFileDir + fn;
+
+        final Document attr = null;
+        final Document request = ClientProtocolUtils.newOutCollectionDocument(getCollection().identifier(), mode, type, attr);
+
+        final InputStream response = this.client.collectionOut(request, getCollection().identifier(), mode);
+        final InputStreamReader in = new InputStreamReader(response, "UTF-8");
+
+        IOUtils.copy(in, new FileOutputStream(filepath), enc);
+
+    }
+
+    public void addRecommendationPair(final String[] rec1, final String[] rec2) throws ConnectionException, ServerException {
+        final Recommendation recom1 = new Recommendation(rec1[0], rec1[1], rec1[2]);
+        final Recommendation recom2 = new Recommendation(rec2[0], rec2[1], rec2[2]);
+        final Artifact[] artifacts = loadMany(new Recommendation[] { recom1, recom2 }, null);
+        final String rec1String = RecommandationUtils.createDataString(artifacts[0].getUuid(), recom1, new NilDatacageTwinPanelInfo("xxxx"));
+        final String rec2String = RecommandationUtils.createDataString(artifacts[1].getUuid(), recom2, new NilDatacageTwinPanelInfo("xxxx"));
+        // TODO: check display name recom1.getDisplayName() TODO: makeDisplayName
+        final String combinedIdNeu = rec1String + "#" + rec2String;
+        this.pairIds.add(combinedIdNeu);
+    }
+
+    protected Data[] getPairData() {
+        final Data[] data = new Data[this.pairIds.size()];
+        int i = 0;
+        for (final String pairId : this.pairIds) {
+            final Data pair = new StringOptionsData("diffids", "diffids", new DataItem[] { new DefaultDataItem(pairId, pairId, pairId) });
+            data[i] = pair;
+            i++;
+        }
+        return data;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gwt-client/src/test/java/test/TestMain.java	Fri Apr 27 11:34:04 2018 +0200
@@ -0,0 +1,41 @@
+package test;
+
+/*
+ * Copyright (c) 2010 by Intevation GmbH
+ *
+ * This program is free software under the LGPL (>=v2.1)
+ * Read the file LGPL.txt coming with the software for details
+ * or visit http://www.gnu.org/licenses/ if it does not exist.
+ */
+
+import java.io.IOException;
+
+import org.dive4elements.river.client.shared.exceptions.ServerException;
+import org.junit.Test;
+
+/**
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class TestMain {
+
+    @Test
+    public void testSInfoFlowDepthMinMax() throws ServerException, IOException {
+        // TODO Auto-generated method stub
+
+        /*
+         * S-Info-calcModes:
+         * sinfo_calc_flow_depth
+         * sinfo_calc_flow_depth_development
+         * sinfo_calc_flow_depth_minmax
+         * sinfo_calc_grounding
+         * Transportkörperhöhen
+         * sinfo_calc_infrastructures_inundation_duration
+         */
+
+        final SinfoTest proof = new SinfoTest("belger", "belger", "sinfo", "sinfo_calc_flow_depth_minmax");
+        proof.addRecommendationPair(new String[] { "staticwqkms", "additionals-wstv-0-103", "sinfo_flowdepth_waterlevels" },
+                new String[] { "bedheight", "bedheight-single-36-2015-FP-2015_0-502", "sinfo_flowdepthminmax_heights" });
+        proof.runTest(true);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gwt-client/src/test/resources/sinfo/flowdepthminmax/sinfo_flowdepthminmax_export.csv	Fri Apr 27 11:34:04 2018 +0200
@@ -0,0 +1,184 @@
+"##Ergebnisausgabe - Beispielfluss - Minimale und Maximale Flietiefe"
+"# FLYS-Version: 3.3.x"
+"# Bearbeiter: belger"
+"# Datum der Erstellung: 26.04.18"
+"# Gewsser: Beispielfluss"
+"# Hhensystem des Flusses: NHN + m "
+"# Bereich (km): 10,000 - 100,000"
+""
+"Fluss-km";"Minimale Flietiefe [m]";"Maximale Flietiefe [m]";"Wasserstand [NHN + m]";"Q [m/s]";"Bezeichnung";"Bezugspegel";"Mittlere Sohlhhe [NHN + m]";"Peilung/Epoche";"Lage"
+""
+"##METADATEN PEILUNG"
+"# Jahr der Peilung: 2015"
+"# Aufnahmeart: Flchenpeilung"
+"# Auswerter: BfG"
+"# Lagesystem: LS 150 oder LS 100 "
+"# Hhensystem: NHN "
+"# ursprngliches Hhensystem: NHN"
+""
+"##METADATEN WASSERSPIEGELLAGE"
+"# Bezeichnung der Wasserspiegellage: null "
+"# Bezugspegel: Torgau"
+""
+"41,600";"2,38";"3,71";"77,06";"85,73";"null";"Torgau";"74,29";"FP-2015_0-502";""
+"41,700";"1,98";"3,19";"77,04";"85,73";"null";"Torgau";"74,42";"FP-2015_0-502";""
+"41,800";"1,93";"3,15";"77,02";"85,73";"null";"Torgau";"74,57";"FP-2015_0-502";""
+"41,900";"1,86";"3,13";"77,00";"85,73";"null";"Torgau";"74,58";"FP-2015_0-502";""
+"42,000";"1,76";"3,75";"76,97";"85,73";"null";"Torgau";"74,60";"FP-2015_0-502";""
+"42,100";"1,80";"3,15";"76,90";"85,73";"null";"Torgau";"74,58";"FP-2015_0-502";""
+"42,200";"1,51";"2,98";"76,83";"85,73";"null";"Torgau";"74,45";"FP-2015_0-502";""
+"42,300";"2,13";"2,92";"76,81";"85,73";"null";"Torgau";"74,30";"FP-2015_0-502";""
+"42,400";"2,23";"3,12";"76,79";"85,73";"null";"Torgau";"74,23";"FP-2015_0-502";""
+"42,500";"1,87";"3,79";"76,78";"85,73";"null";"Torgau";"73,99";"FP-2015_0-502";""
+"42,600";"1,78";"4,07";"76,76";"85,73";"null";"Torgau";"73,93";"FP-2015_0-502";""
+"42,700";"1,78";"4,58";"76,75";"85,73";"null";"Torgau";"74,00";"FP-2015_0-502";""
+"42,800";"1,84";"4,71";"76,73";"85,73";"null";"Torgau";"73,96";"FP-2015_0-502";""
+"42,900";"1,97";"4,81";"76,72";"85,73";"null";"Torgau";"73,64";"FP-2015_0-502";""
+"43,000";"1,74";"4,98";"76,70";"85,73";"null";"Torgau";"73,78";"FP-2015_0-502";""
+"43,100";"1,97";"3,84";"76,70";"85,73";"null";"Torgau";"74,06";"FP-2015_0-502";""
+"43,200";"2,06";"3,77";"76,69";"85,73";"null";"Torgau";"74,00";"FP-2015_0-502";""
+"43,300";"2,25";"2,99";"76,68";"85,73";"null";"Torgau";"74,09";"FP-2015_0-502";""
+"43,400";"2,17";"3,27";"76,66";"85,73";"null";"Torgau";"74,03";"FP-2015_0-502";""
+"43,500";"1,86";"3,14";"76,64";"85,73";"null";"Torgau";"73,96";"FP-2015_0-502";""
+"43,600";"1,77";"3,43";"76,61";"85,73";"null";"Torgau";"74,07";"FP-2015_0-502";""
+"43,700";"1,72";"4,10";"76,58";"85,73";"null";"Torgau";"74,08";"FP-2015_0-502";""
+"43,800";"1,77";"3,57";"76,54";"85,73";"null";"Torgau";"74,10";"FP-2015_0-502";""
+"43,900";"1,79";"3,42";"76,53";"85,73";"null";"Torgau";"74,00";"FP-2015_0-502";""
+"44,000";"1,71";"3,60";"76,51";"85,73";"null";"Torgau";"74,13";"FP-2015_0-502";""
+"44,100";"1,92";"3,36";"76,49";"85,73";"null";"Torgau";"74,08";"FP-2015_0-502";""
+"44,200";"2,06";"3,48";"76,46";"85,73";"null";"Torgau";"73,86";"FP-2015_0-502";""
+"44,300";"1,84";"3,89";"76,43";"85,73";"null";"Torgau";"73,80";"FP-2015_0-502";""
+"44,400";"1,88";"3,70";"76,40";"85,73";"null";"Torgau";"73,78";"FP-2015_0-502";""
+"44,500";"2,01";"5,10";"76,38";"85,73";"null";"Torgau";"73,40";"FP-2015_0-502";""
+"44,600";"2,34";"5,11";"76,36";"85,73";"null";"Torgau";"73,08";"FP-2015_0-502";""
+"44,700";"2,83";"4,23";"76,36";"85,73";"null";"Torgau";"73,12";"FP-2015_0-502";""
+"44,800";"2,45";"3,54";"76,35";"85,73";"null";"Torgau";"73,25";"FP-2015_0-502";""
+"44,900";"2,34";"3,66";"76,34";"85,73";"null";"Torgau";"73,34";"FP-2015_0-502";""
+"45,000";"2,04";"3,41";"76,33";"85,73";"null";"Torgau";"73,53";"FP-2015_0-502";""
+"45,100";"1,92";"3,43";"76,33";"85,73";"null";"Torgau";"73,62";"FP-2015_0-502";""
+"45,200";"2,43";"3,64";"76,32";"85,73";"null";"Torgau";"73,38";"FP-2015_0-502";""
+"45,300";"2,34";"3,84";"76,31";"85,73";"null";"Torgau";"73,31";"FP-2015_0-502";""
+"45,400";"1,98";"4,03";"76,30";"85,73";"null";"Torgau";"73,19";"FP-2015_0-502";""
+"45,500";"2,40";"4,01";"76,30";"85,73";"null";"Torgau";"73,09";"FP-2015_0-502";""
+"45,600";"2,32";"3,93";"76,29";"85,73";"null";"Torgau";"73,07";"FP-2015_0-502";""
+"45,700";"2,15";"3,77";"76,28";"85,73";"null";"Torgau";"73,37";"FP-2015_0-502";""
+"45,800";"2,20";"4,16";"76,27";"85,73";"null";"Torgau";"73,37";"FP-2015_0-502";"Hafen: Torgau"
+"45,900";"2,33";"3,85";"76,26";"85,73";"null";"Torgau";"73,21";"FP-2015_0-502";""
+"46,000";"2,04";"3,67";"76,25";"85,73";"null";"Torgau";"73,50";"FP-2015_0-502";""
+"46,100";"1,95";"3,81";"76,24";"85,73";"null";"Torgau";"73,45";"FP-2015_0-502";"Brcke: Torgau -Strae B87"
+"46,200";"1,92";"2,93";"76,23";"85,73";"null";"Torgau";"73,80";"FP-2015_0-502";""
+"46,300";"1,96";"2,94";"76,17";"85,73";"null";"Torgau";"73,75";"FP-2015_0-502";""
+"46,400";"1,96";"2,82";"76,10";"85,73";"null";"Torgau";"73,73";"FP-2015_0-502";""
+"46,500";"1,87";"3,17";"76,07";"85,73";"null";"Torgau";"73,73";"FP-2015_0-502";""
+"46,600";"2,02";"2,97";"76,04";"85,73";"null";"Torgau";"73,73";"FP-2015_0-502";""
+"46,700";"1,86";"2,81";"76,01";"85,73";"null";"Torgau";"73,66";"FP-2015_0-502";""
+"46,800";"2,08";"2,83";"75,98";"85,73";"null";"Torgau";"73,63";"FP-2015_0-502";"Geschiebemessstelle: Torgau"
+"46,900";"2,07";"2,99";"75,97";"85,73";"null";"Torgau";"73,57";"FP-2015_0-502";""
+"47,000";"2,11";"3,08";"75,97";"85,73";"null";"Torgau";"73,38";"FP-2015_0-502";""
+"47,100";"2,34";"3,03";"75,95";"85,73";"null";"Torgau";"73,34";"FP-2015_0-502";""
+"47,200";"2,08";"3,11";"75,92";"85,73";"null";"Torgau";"73,30";"FP-2015_0-502";""
+"47,300";"2,35";"4,01";"75,90";"85,73";"null";"Torgau";"73,09";"FP-2015_0-502";""
+"47,400";"2,37";"4,22";"75,88";"85,73";"null";"Torgau";"72,86";"FP-2015_0-502";""
+"47,500";"2,52";"4,36";"75,88";"85,73";"null";"Torgau";"72,56";"FP-2015_0-502";""
+"47,600";"2,61";"4,05";"75,88";"85,73";"null";"Torgau";"72,52";"FP-2015_0-502";""
+"47,700";"2,39";"3,89";"75,87";"85,73";"null";"Torgau";"72,84";"FP-2015_0-502";""
+"47,800";"2,32";"3,98";"75,86";"85,73";"null";"Torgau";"72,81";"FP-2015_0-502";""
+"47,900";"2,52";"4,13";"75,84";"85,73";"null";"Torgau";"72,63";"FP-2015_0-502";""
+"48,000";"2,17";"3,73";"75,82";"85,73";"null";"Torgau";"72,73";"FP-2015_0-502";""
+"48,100";"2,27";"3,60";"75,81";"85,73";"null";"Torgau";"72,88";"FP-2015_0-502";""
+"48,200";"2,14";"3,40";"75,79";"85,73";"null";"Torgau";"72,85";"FP-2015_0-502";""
+"48,300";"2,17";"3,50";"75,77";"85,73";"null";"Torgau";"72,94";"FP-2015_0-502";""
+"48,400";"2,01";"3,92";"75,74";"85,73";"null";"Torgau";"72,72";"FP-2015_0-502";""
+"48,500";"2,07";"3,18";"75,73";"85,73";"null";"Torgau";"72,95";"FP-2015_0-502";""
+"48,600";"2,10";"3,40";"75,71";"85,73";"null";"Torgau";"72,89";"FP-2015_0-502";""
+"48,700";"1,82";"4,02";"75,69";"85,73";"null";"Torgau";"72,70";"FP-2015_0-502";""
+"48,800";"1,48";"4,65";"75,66";"85,73";"null";"Torgau";"72,64";"FP-2015_0-502";""
+"48,900";"1,47";"5,03";"75,63";"85,73";"null";"Torgau";"72,48";"FP-2015_0-502";""
+"49,000";"2,53";"4,05";"75,60";"85,73";"null";"Torgau";"72,29";"FP-2015_0-502";""
+"49,100";"2,02";"3,44";"75,59";"85,73";"null";"Torgau";"72,75";"FP-2015_0-502";""
+"49,200";"2,31";"3,39";"75,58";"85,73";"null";"Torgau";"72,84";"FP-2015_0-502";""
+"49,300";"2,02";"3,10";"75,53";"85,73";"null";"Torgau";"72,94";"FP-2015_0-502";""
+"49,400";"2,01";"3,57";"75,48";"85,73";"null";"Torgau";"72,79";"FP-2015_0-502";""
+"49,500";"2,47";"3,11";"75,48";"85,73";"null";"Torgau";"72,59";"FP-2015_0-502";""
+"49,600";"1,74";"3,11";"75,48";"85,73";"null";"Torgau";"72,80";"FP-2015_0-502";""
+"49,700";"1,85";"4,02";"75,45";"85,73";"null";"Torgau";"72,89";"FP-2015_0-502";""
+"49,800";"1,98";"3,65";"75,42";"85,73";"null";"Torgau";"72,66";"FP-2015_0-502";""
+"49,900";"2,20";"3,61";"75,42";"85,73";"null";"Torgau";"72,39";"FP-2015_0-502";""
+"50,000";"2,03";"3,48";"75,41";"85,73";"null";"Torgau";"72,60";"FP-2015_0-502";""
+"50,100";"1,87";"3,48";"75,38";"85,73";"null";"Torgau";"72,60";"FP-2015_0-502";""
+"50,200";"1,88";"4,10";"75,35";"85,73";"null";"Torgau";"72,38";"FP-2015_0-502";""
+"50,300";"2,03";"4,32";"75,33";"85,73";"null";"Torgau";"72,16";"FP-2015_0-502";""
+"50,400";"1,91";"3,96";"75,30";"85,73";"null";"Torgau";"72,44";"FP-2015_0-502";""
+"50,500";"1,88";"3,46";"75,28";"85,73";"null";"Torgau";"72,64";"FP-2015_0-502";""
+"50,600";"1,93";"3,27";"75,26";"85,73";"null";"Torgau";"72,67";"FP-2015_0-502";""
+"50,700";"1,76";"3,35";"75,22";"85,73";"null";"Torgau";"72,67";"FP-2015_0-502";""
+"50,800";"1,84";"3,24";"75,17";"85,73";"null";"Torgau";"72,65";"FP-2015_0-502";""
+"50,900";"1,84";"3,47";"75,13";"85,73";"null";"Torgau";"72,46";"FP-2015_0-502";""
+"51,000";"1,50";"3,81";"75,08";"85,73";"null";"Torgau";"72,41";"FP-2015_0-502";""
+"51,100";"1,63";"4,71";"75,02";"85,73";"null";"Torgau";"72,05";"FP-2015_0-502";""
+"51,200";"2,03";"4,68";"74,97";"85,73";"null";"Torgau";"71,92";"FP-2015_0-502";""
+"51,300";"2,21";"4,08";"74,96";"85,73";"null";"Torgau";"72,00";"FP-2015_0-502";""
+"51,400";"1,85";"4,51";"74,94";"85,73";"null";"Torgau";"71,86";"FP-2015_0-502";""
+"51,500";"1,94";"3,46";"74,92";"85,73";"null";"Torgau";"72,12";"FP-2015_0-502";""
+"51,600";"1,77";"3,48";"74,90";"85,73";"null";"Torgau";"72,10";"FP-2015_0-502";""
+"94,100";"2,16";"3,16";"66,61";"91,31";"null";"auerh. d. Bez.pegels";"63,90";"FP-2015_0-502";""
+"94,200";"2,46";"2,95";"66,60";"91,31";"null";"auerh. d. Bez.pegels";"63,91";"FP-2015_0-502";""
+"94,300";"2,27";"3,24";"66,58";"91,31";"null";"auerh. d. Bez.pegels";"63,91";"FP-2015_0-502";""
+"94,400";"1,99";"3,03";"66,55";"91,31";"null";"auerh. d. Bez.pegels";"63,94";"FP-2015_0-502";""
+"94,500";"2,01";"3,00";"66,52";"91,31";"null";"auerh. d. Bez.pegels";"63,97";"FP-2015_0-502";""
+"94,600";"1,95";"2,75";"66,49";"91,31";"null";"auerh. d. Bez.pegels";"64,10";"FP-2015_0-502";"HW-Schutz: Galliner-Deich"
+"94,700";"1,89";"2,88";"66,47";"91,31";"null";"auerh. d. Bez.pegels";"64,12";"FP-2015_0-502";""
+"94,800";"1,99";"3,67";"66,44";"91,31";"null";"auerh. d. Bez.pegels";"64,04";"FP-2015_0-502";""
+"94,900";"1,87";"3,85";"66,41";"91,31";"null";"auerh. d. Bez.pegels";"63,94";"FP-2015_0-502";""
+"95,000";"2,14";"3,33";"66,37";"91,31";"null";"auerh. d. Bez.pegels";"63,84";"FP-2015_0-502";""
+"95,100";"2,25";"3,06";"66,34";"91,31";"null";"auerh. d. Bez.pegels";"63,65";"FP-2015_0-502";""
+"95,200";"1,87";"3,04";"66,31";"91,31";"null";"auerh. d. Bez.pegels";"63,65";"FP-2015_0-502";""
+"95,300";"2,03";"3,05";"66,29";"91,31";"null";"auerh. d. Bez.pegels";"63,61";"FP-2015_0-502";""
+"95,400";"1,97";"2,92";"66,27";"91,31";"null";"auerh. d. Bez.pegels";"63,77";"FP-2015_0-502";""
+"95,500";"2,29";"2,89";"66,23";"91,31";"null";"auerh. d. Bez.pegels";"63,70";"FP-2015_0-502";""
+"95,600";"2,24";"2,85";"66,18";"91,31";"null";"auerh. d. Bez.pegels";"63,77";"FP-2015_0-502";""
+"95,700";"2,06";"2,98";"66,15";"91,31";"null";"auerh. d. Bez.pegels";"63,67";"FP-2015_0-502";""
+"95,800";"2,04";"3,04";"66,12";"91,31";"null";"auerh. d. Bez.pegels";"63,52";"FP-2015_0-502";""
+"95,900";"2,16";"3,54";"66,10";"91,31";"null";"auerh. d. Bez.pegels";"63,51";"FP-2015_0-502";""
+"96,000";"2,10";"3,73";"66,07";"91,31";"null";"auerh. d. Bez.pegels";"63,25";"FP-2015_0-502";""
+"96,100";"2,32";"3,80";"66,05";"91,31";"null";"auerh. d. Bez.pegels";"63,08";"FP-2015_0-502";""
+"96,200";"2,28";"3,37";"66,02";"91,31";"null";"auerh. d. Bez.pegels";"63,17";"FP-2015_0-502";""
+"96,300";"2,25";"3,13";"66,02";"91,31";"null";"auerh. d. Bez.pegels";"63,28";"FP-2015_0-502";""
+"96,400";"2,18";"3,09";"66,01";"91,31";"null";"auerh. d. Bez.pegels";"63,45";"FP-2015_0-502";""
+"96,500";"2,13";"3,07";"65,99";"91,31";"null";"auerh. d. Bez.pegels";"63,51";"FP-2015_0-502";""
+"96,600";"2,03";"3,07";"65,97";"91,31";"null";"auerh. d. Bez.pegels";"63,30";"FP-2015_0-502";""
+"96,700";"1,79";"3,62";"65,96";"91,31";"null";"auerh. d. Bez.pegels";"63,36";"FP-2015_0-502";""
+"96,800";"1,74";"3,55";"65,94";"91,31";"null";"auerh. d. Bez.pegels";"63,26";"FP-2015_0-502";""
+"96,900";"2,11";"3,21";"65,92";"91,31";"null";"auerh. d. Bez.pegels";"63,12";"FP-2015_0-502";""
+"97,000";"2,03";"2,96";"65,90";"91,31";"null";"auerh. d. Bez.pegels";"63,36";"FP-2015_0-502";""
+"97,100";"2,05";"2,72";"65,87";"91,31";"null";"auerh. d. Bez.pegels";"63,49";"FP-2015_0-502";"Zufluss: Alte Elbe"
+"97,200";"2,23";"4,19";"65,84";"91,31";"null";"auerh. d. Bez.pegels";"63,27";"FP-2015_0-502";""
+"97,300";"1,97";"4,05";"65,82";"91,31";"null";"auerh. d. Bez.pegels";"63,07";"FP-2015_0-502";""
+"97,400";"2,06";"3,45";"65,80";"91,31";"null";"auerh. d. Bez.pegels";"62,90";"FP-2015_0-502";""
+"97,500";"1,77";"3,87";"65,80";"91,31";"null";"auerh. d. Bez.pegels";"62,85";"FP-2015_0-502";""
+"97,600";"1,99";"3,80";"65,79";"91,31";"null";"auerh. d. Bez.pegels";"62,94";"FP-2015_0-502";""
+"97,700";"2,04";"3,43";"65,77";"91,31";"null";"auerh. d. Bez.pegels";"63,07";"FP-2015_0-502";""
+"97,800";"1,93";"3,56";"65,74";"91,31";"null";"auerh. d. Bez.pegels";"63,11";"FP-2015_0-502";""
+"97,900";"2,14";"3,46";"65,72";"91,31";"null";"auerh. d. Bez.pegels";"63,07";"FP-2015_0-502";""
+"98,000";"2,18";"3,27";"65,70";"91,31";"null";"auerh. d. Bez.pegels";"62,99";"FP-2015_0-502";""
+"98,100";"2,21";"3,79";"65,69";"91,31";"null";"auerh. d. Bez.pegels";"63,00";"FP-2015_0-502";""
+"98,200";"2,00";"3,47";"65,67";"91,31";"null";"auerh. d. Bez.pegels";"62,99";"FP-2015_0-502";""
+"98,300";"1,90";"3,66";"65,66";"91,31";"null";"auerh. d. Bez.pegels";"63,26";"FP-2015_0-502";""
+"98,400";"2,06";"3,30";"65,64";"91,31";"null";"auerh. d. Bez.pegels";"63,25";"FP-2015_0-502";""
+"98,500";"1,95";"3,89";"65,61";"91,31";"null";"auerh. d. Bez.pegels";"63,22";"FP-2015_0-502";""
+"98,600";"1,93";"2,96";"65,58";"91,31";"null";"auerh. d. Bez.pegels";"63,28";"FP-2015_0-502";""
+"98,700";"1,90";"2,95";"65,54";"91,31";"null";"auerh. d. Bez.pegels";"62,97";"FP-2015_0-502";""
+"98,800";"1,88";"3,27";"65,50";"91,31";"null";"auerh. d. Bez.pegels";"62,77";"FP-2015_0-502";""
+"98,900";"2,08";"3,55";"65,47";"91,31";"null";"auerh. d. Bez.pegels";"62,57";"FP-2015_0-502";""
+"99,000";"2,18";"3,81";"65,45";"91,31";"null";"auerh. d. Bez.pegels";"62,37";"FP-2015_0-502";""
+"99,100";"2,05";"3,70";"65,45";"91,31";"null";"auerh. d. Bez.pegels";"62,51";"FP-2015_0-502";""
+"99,200";"1,90";"4,12";"65,44";"91,31";"null";"auerh. d. Bez.pegels";"62,50";"FP-2015_0-502";""
+"99,300";"2,11";"3,76";"65,43";"91,31";"null";"auerh. d. Bez.pegels";"62,60";"FP-2015_0-502";""
+"99,400";"2,11";"3,55";"65,41";"91,31";"null";"auerh. d. Bez.pegels";"62,80";"FP-2015_0-502";""
+"99,500";"2,22";"2,83";"65,40";"91,31";"null";"auerh. d. Bez.pegels";"62,84";"FP-2015_0-502";""
+"99,600";"2,21";"2,75";"65,38";"91,31";"null";"auerh. d. Bez.pegels";"62,92";"FP-2015_0-502";""
+"99,700";"2,23";"2,88";"65,36";"91,31";"null";"auerh. d. Bez.pegels";"62,91";"FP-2015_0-502";""
+"99,800";"2,15";"2,84";"65,34";"91,31";"null";"auerh. d. Bez.pegels";"62,88";"FP-2015_0-502";""
+"99,900";"2,17";"2,75";"65,31";"91,31";"null";"auerh. d. Bez.pegels";"62,79";"FP-2015_0-502";""
+"100,000";"2,13";"2,78";"65,29";"91,31";"null";"auerh. d. Bez.pegels";"62,84";"FP-2015_0-502";""
+""

http://dive4elements.wald.intevation.org