changeset 8989:2693bfaf503d

Fixed several BigDecimal(double) creations by BigDecimal(String) parsing to avoid unnecessary decimal digits
author mschaefer
date Mon, 09 Apr 2018 09:07:00 +0200
parents ae76f618d990
children 07dcedddf839
files backend/src/main/java/org/dive4elements/river/importer/common/AbstractParser.java backend/src/main/java/org/dive4elements/river/importer/parsers/BedHeightParser.java backend/src/main/java/org/dive4elements/river/importer/parsers/FlowVelocityMeasurementParser.java backend/src/main/java/org/dive4elements/river/importer/parsers/FlowVelocityModelParser.java backend/src/main/java/org/dive4elements/river/importer/parsers/MeasurementStationsParser.java backend/src/main/java/org/dive4elements/river/importer/parsers/MorphologicalWidthParser.java backend/src/main/java/org/dive4elements/river/importer/parsers/SedimentDensityParser.java backend/src/main/java/org/dive4elements/river/importer/parsers/WaterlevelDifferencesParser.java backend/src/main/java/org/dive4elements/river/importer/parsers/WaterlevelParser.java
diffstat 9 files changed, 386 insertions(+), 418 deletions(-) [+]
line wrap: on
line diff
--- a/backend/src/main/java/org/dive4elements/river/importer/common/AbstractParser.java	Sun Apr 08 18:09:32 2018 +0200
+++ b/backend/src/main/java/org/dive4elements/river/importer/common/AbstractParser.java	Mon Apr 09 09:07:00 2018 +0200
@@ -16,6 +16,7 @@
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.LineNumberReader;
+import java.math.BigDecimal;
 import java.text.NumberFormat;
 import java.text.ParseException;
 import java.util.ArrayList;
@@ -262,6 +263,13 @@
     }
 
     /**
+     * Parses a number string as a BigDecimal, replacing a comma with a dot first
+     */
+    public static BigDecimal parseDecimal(final String text) throws NumberFormatException {
+        return new BigDecimal(text.replace(',', '.'));
+    }
+
+    /**
      * Gets the class's logger
      */
     protected abstract Logger getLog();
--- a/backend/src/main/java/org/dive4elements/river/importer/parsers/BedHeightParser.java	Sun Apr 08 18:09:32 2018 +0200
+++ b/backend/src/main/java/org/dive4elements/river/importer/parsers/BedHeightParser.java	Mon Apr 09 09:07:00 2018 +0200
@@ -37,6 +37,7 @@
 import org.dive4elements.river.importer.ImportTimeInterval;
 import org.dive4elements.river.importer.ImportUnit;
 import org.dive4elements.river.importer.ImporterSession;
+import org.dive4elements.river.importer.common.AbstractParser;
 import org.dive4elements.river.model.BedHeightType;
 
 public class BedHeightParser {
@@ -284,12 +285,12 @@
             final String a = m.group(1).replace(";", "").trim();
             final String b = m.group(2).replace(";", "").trim();
             try {
-                final BigDecimal lower = new BigDecimal(nf.parse(a).doubleValue());
-                final BigDecimal upper = new BigDecimal(nf.parse(b).doubleValue());
+                final BigDecimal lower = AbstractParser.parseDecimal(a);
+                final BigDecimal upper = AbstractParser.parseDecimal(b);
                 obj.setRange(new ImportRange(lower, upper));
                 return true;
             }
-            catch (final ParseException e) {
+            catch (final Exception e) {
                 log.warn("BHP: could not parse range", e);
             }
         }
--- a/backend/src/main/java/org/dive4elements/river/importer/parsers/FlowVelocityMeasurementParser.java	Sun Apr 08 18:09:32 2018 +0200
+++ b/backend/src/main/java/org/dive4elements/river/importer/parsers/FlowVelocityMeasurementParser.java	Mon Apr 09 09:07:00 2018 +0200
@@ -8,61 +8,58 @@
 
 package org.dive4elements.river.importer.parsers;
 
-import org.dive4elements.river.importer.ImportFlowVelocityMeasurement;
-import org.dive4elements.river.importer.ImportFlowVelocityMeasurementValue;
-
 import java.math.BigDecimal;
-
 import java.text.DateFormat;
 import java.text.NumberFormat;
-import java.text.ParseException;
 import java.text.SimpleDateFormat;
-
 import java.util.ArrayList;
 import java.util.List;
 
 import org.apache.log4j.Logger;
+import org.dive4elements.river.importer.ImportFlowVelocityMeasurement;
+import org.dive4elements.river.importer.ImportFlowVelocityMeasurementValue;
+import org.dive4elements.river.importer.common.AbstractParser;
 public class FlowVelocityMeasurementParser extends LineParser {
 
     private static final Logger log =
-        Logger.getLogger(FlowVelocityMeasurementParser.class);
+            Logger.getLogger(FlowVelocityMeasurementParser.class);
 
     private static final NumberFormat nf =
-        NumberFormat.getInstance(DEFAULT_LOCALE);
+            NumberFormat.getInstance(DEFAULT_LOCALE);
 
     private static final DateFormat df =
-        new SimpleDateFormat("dd.MM.yyyy HH:mm:ss");
+            new SimpleDateFormat("dd.MM.yyyy HH:mm:ss");
 
 
-    private List<ImportFlowVelocityMeasurement> measurements;
+    private final List<ImportFlowVelocityMeasurement> measurements;
 
     private ImportFlowVelocityMeasurement current;
 
 
     public FlowVelocityMeasurementParser() {
-        measurements = new ArrayList<ImportFlowVelocityMeasurement>();
+        this.measurements = new ArrayList<>();
     }
 
 
     public List<ImportFlowVelocityMeasurement> getMeasurements() {
-        return measurements;
+        return this.measurements;
     }
 
     @Override
     protected void reset() {
-        current = new ImportFlowVelocityMeasurement();
+        this.current = new ImportFlowVelocityMeasurement();
     }
 
 
     @Override
     protected void finish() {
-        current.setDescription(fileName);
-        measurements.add(current);
+        this.current.setDescription(this.fileName);
+        this.measurements.add(this.current);
     }
 
 
     @Override
-    protected void handleLine(int lineNum, String line) {
+    protected void handleLine(final int lineNum, final String line) {
         if (line.startsWith(START_META_CHAR)) {
             handleMetaLine(stripMetaLine(line));
         }
@@ -72,12 +69,12 @@
     }
 
 
-    public void handleMetaLine(String line) {
+    public void handleMetaLine(final String line) {
     }
 
 
-    public void handleDataLine(String line) {
-        String[] cols = line.split(SEPERATOR_CHAR);
+    public void handleDataLine(final String line) {
+        final String[] cols = line.split(SEPERATOR_CHAR);
 
         if (cols.length < 8) {
             log.warn("skip invalid data line: '" + line + "'");
@@ -85,24 +82,17 @@
         }
 
         try {
-            double km     = nf.parse(cols[1]).doubleValue();
-            double w      = nf.parse(cols[5]).doubleValue();
-            double q      = nf.parse(cols[6]).doubleValue();
-            double v      = nf.parse(cols[7]).doubleValue();
-
-            String timestr     = cols[3] + " " + cols[4];
-            String description = cols.length > 8 ? cols[8] : null;
+            final BigDecimal km = AbstractParser.parseDecimal(cols[1]);
+            final BigDecimal w = AbstractParser.parseDecimal(cols[5]);
+            final BigDecimal q = AbstractParser.parseDecimal(cols[6]);
+            final BigDecimal v = AbstractParser.parseDecimal(cols[7]);
 
-            current.addValue(new ImportFlowVelocityMeasurementValue(
-                df.parse(timestr),
-                new BigDecimal(km),
-                new BigDecimal(w),
-                new BigDecimal(q),
-                new BigDecimal(v),
-                description
-            ));
+            final String timestr     = cols[3] + " " + cols[4];
+            final String description = cols.length > 8 ? cols[8] : null;
+
+            this.current.addValue(new ImportFlowVelocityMeasurementValue(df.parse(timestr), km, w, q, v, description));
         }
-        catch (ParseException pe) {
+        catch (final Exception pe) {
             log.warn("Unparseable flow velocity values:", pe);
         }
     }
--- a/backend/src/main/java/org/dive4elements/river/importer/parsers/FlowVelocityModelParser.java	Sun Apr 08 18:09:32 2018 +0200
+++ b/backend/src/main/java/org/dive4elements/river/importer/parsers/FlowVelocityModelParser.java	Mon Apr 09 09:07:00 2018 +0200
@@ -10,10 +10,8 @@
 
 import java.io.File;
 import java.io.IOException;
-
 import java.math.BigDecimal;
 import java.text.NumberFormat;
-import java.text.ParseException;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.TreeSet;
@@ -21,48 +19,48 @@
 import java.util.regex.Pattern;
 
 import org.apache.log4j.Logger;
-
+import org.dive4elements.river.backend.utils.EpsilonComparator;
 import org.dive4elements.river.importer.ImportDischargeZone;
 import org.dive4elements.river.importer.ImportFlowVelocityModel;
 import org.dive4elements.river.importer.ImportFlowVelocityModelValue;
-import org.dive4elements.river.backend.utils.EpsilonComparator;
+import org.dive4elements.river.importer.common.AbstractParser;
 
 
 public class FlowVelocityModelParser extends LineParser {
 
     private static final Logger log =
-        Logger.getLogger(FlowVelocityModelParser.class);
+            Logger.getLogger(FlowVelocityModelParser.class);
 
     private static final Pattern META_REGEX =
-        Pattern.compile(".*Rechnung [unter ]*(.*) \\(Pegel (.*)\\).*");
+            Pattern.compile(".*Rechnung [unter ]*(.*) \\(Pegel (.*)\\).*");
 
     private static final Pattern META_GAUGE =
-        Pattern.compile("(.*) Q=(\\w*)m3/s");
+            Pattern.compile("(.*) Q=(\\w*)m3/s");
 
     private static final Pattern META_MAINVALUE_A =
-        Pattern.compile("([a-zA-Z]+)+(\\d+)*[\\w()]*");
+            Pattern.compile("([a-zA-Z]+)+(\\d+)*[\\w()]*");
 
     private static final Pattern META_MAINVALUE_B =
-        Pattern.compile(
-            "(([a-zA-Z]+)+(\\d+)*)\\s*-\\s*(([a-zA-Z]+)+(\\d+)*\\S*)");
+            Pattern.compile(
+                    "(([a-zA-Z]+)+(\\d+)*)\\s*-\\s*(([a-zA-Z]+)+(\\d+)*\\S*)");
 
     private static final Pattern META_MAINVALUE_C =
-        Pattern.compile("([0-9]++)\\s?(\\S*)|([0-9]++,[0-9]++)\\s?(\\S*)");
+            Pattern.compile("([0-9]++)\\s?(\\S*)|([0-9]++,[0-9]++)\\s?(\\S*)");
 
     private static final Pattern META_MAINVALUE_D =
-        Pattern.compile(
-            "(([0-9]*)\\s?(\\w*)|([0-9]++,[0-9]++)\\s?(\\w*))\\s*"
-            + "bis (([0-9]*)\\s?(\\S*)|([0-9]++,[0-9]++)\\s?(\\S*))");
+            Pattern.compile(
+                    "(([0-9]*)\\s?(\\w*)|([0-9]++,[0-9]++)\\s?(\\w*))\\s*"
+                            + "bis (([0-9]*)\\s?(\\S*)|([0-9]++,[0-9]++)\\s?(\\S*))");
 
     private static final Pattern META_MAINVALUE_E =
-        Pattern.compile(
-            "(([a-zA-Z]+)+(\\d+)*)\\s*bis (([a-zA-Z]+)+(\\d+)*\\S*)");
+            Pattern.compile(
+                    "(([a-zA-Z]+)+(\\d+)*)\\s*bis (([a-zA-Z]+)+(\\d+)*\\S*)");
 
     private static final NumberFormat nf =
-        NumberFormat.getInstance(DEFAULT_LOCALE);
+            NumberFormat.getInstance(DEFAULT_LOCALE);
 
 
-    private List<ImportFlowVelocityModel> models;
+    private final List<ImportFlowVelocityModel> models;
 
     private ImportFlowVelocityModel current;
 
@@ -72,38 +70,38 @@
 
 
     public FlowVelocityModelParser() {
-        models = new ArrayList<ImportFlowVelocityModel>();
-        kmExists = new TreeSet<Double>(EpsilonComparator.CMP);
+        this.models = new ArrayList<>();
+        this.kmExists = new TreeSet<>(EpsilonComparator.CMP);
     }
 
 
     public List<ImportFlowVelocityModel> getModels() {
-        return models;
+        return this.models;
     }
 
     @Override
-    public void parse(File file) throws IOException {
-        description = file.getName();
+    public void parse(final File file) throws IOException {
+        this.description = file.getName();
 
         super.parse(file);
     }
 
     @Override
     protected void reset() {
-        current = new ImportFlowVelocityModel(description);
-        kmExists.clear();
+        this.current = new ImportFlowVelocityModel(this.description);
+        this.kmExists.clear();
     }
 
 
     @Override
     protected void finish() {
-        models.add(current);
+        this.models.add(this.current);
         // description = null;
     }
 
 
     @Override
-    protected void handleLine(int lineNum, String line) {
+    protected void handleLine(final int lineNum, final String line) {
         if (line.startsWith(START_META_CHAR)) {
             handleMetaLine(stripMetaLine(line));
         }
@@ -113,16 +111,16 @@
     }
 
 
-    protected void handleMetaLine(String line) {
-        Matcher m = META_REGEX.matcher(line);
+    protected void handleMetaLine(final String line) {
+        final Matcher m = META_REGEX.matcher(line);
 
         if (m.matches()) {
-            String mainValueStr = m.group(1);
+            final String mainValueStr = m.group(1);
             log.debug("mainValueStr = '" + mainValueStr + "'");
-            String gaugeStr     = m.group(2);
+            final String gaugeStr     = m.group(2);
 
-            Object[] valueData = handleMainValueString(mainValueStr);
-            Object[] gaugeData = handleGaugeString(gaugeStr);
+            final Object[] valueData = handleMainValueString(mainValueStr);
+            final Object[] gaugeData = handleGaugeString(gaugeStr);
 
             if (valueData == null || valueData.length < 2) {
                 log.warn("skip invalid MainValue part in '" + line + "'");
@@ -142,102 +140,102 @@
                 log.debug("   upper: " + valueData[1]);
             }
 
-            current.setDischargeZone(new ImportDischargeZone(
-                (String) gaugeData[0],
-                (BigDecimal) gaugeData[1],
-                (String) valueData[0],
-                (String) valueData[1]
-            ));
+            this.current.setDischargeZone(new ImportDischargeZone(
+                    (String) gaugeData[0],
+                    (BigDecimal) gaugeData[1],
+                    (String) valueData[0],
+                    (String) valueData[1]
+                    ));
         }
     }
 
 
-    protected Object[] handleMainValueString(String mainValueStr) {
-        Matcher mA = META_MAINVALUE_A.matcher(mainValueStr.trim());
+    protected Object[] handleMainValueString(final String mainValueStr) {
+        final Matcher mA = META_MAINVALUE_A.matcher(mainValueStr.trim());
         if (mA.matches()) {
             log.debug("mainValueStr matches META_MAINVALUE_A");
-            String name = mA.group(0);
+            final String name = mA.group(0);
 
             return new Object[] { name, name };
         }
 
-        Matcher mB = META_MAINVALUE_B.matcher(mainValueStr.trim());
+        final Matcher mB = META_MAINVALUE_B.matcher(mainValueStr.trim());
         if (mB.matches()) {
             log.debug("mainValueStr matches META_MAINVALUE_B");
-            String lower = mB.group(1);
-            String upper = mB.group(4);
+            final String lower = mB.group(1);
+            final String upper = mB.group(4);
 
             return new Object[] { lower, upper };
         }
 
-        Matcher mC = META_MAINVALUE_C.matcher(mainValueStr.trim());
+        final Matcher mC = META_MAINVALUE_C.matcher(mainValueStr.trim());
         if (mC.matches()) {
             log.debug("mainValueStr matches META_MAINVALUE_C");
-            String facA  = mC.group(1);
-            String nameA = mC.group(2);
-            String facB  = mC.group(3);
-            String nameB = mC.group(4);
+            final String facA  = mC.group(1);
+            final String nameA = mC.group(2);
+            final String facB  = mC.group(3);
+            final String nameB = mC.group(4);
 
-            String fac  = facA  != null ? facA  : facB;
-            String name = nameA != null ? nameA : nameB;
+            final String fac  = facA  != null ? facA  : facB;
+            final String name = nameA != null ? nameA : nameB;
 
-            String mainValue = fac + " " + name;
+            final String mainValue = fac + " " + name;
 
             return new Object[] { mainValue, mainValue };
         }
 
-        Matcher mD = META_MAINVALUE_D.matcher(mainValueStr.trim());
+        final Matcher mD = META_MAINVALUE_D.matcher(mainValueStr.trim());
         if (mD.matches()) {
             log.debug("mainValueStr matches META_MAINVALUE_D");
-            String loFacA  = mD.group(2);
-            String loNameA = mD.group(3);
-            String loFacB  = mD.group(4);
-            String loNameB = mD.group(5);
+            final String loFacA  = mD.group(2);
+            final String loNameA = mD.group(3);
+            final String loFacB  = mD.group(4);
+            final String loNameB = mD.group(5);
 
-            String upFacA  = mD.group(7);
-            String upNameA = mD.group(8);
-            String upFacB  = mD.group(9);
-            String upNameB = mD.group(10);
+            final String upFacA  = mD.group(7);
+            final String upNameA = mD.group(8);
+            final String upFacB  = mD.group(9);
+            final String upNameB = mD.group(10);
 
-            String loFac  = loFacA  != null ? loFacA  : loFacB;
-            String loName = loNameA != null ? loNameA : loNameB;
+            final String loFac  = loFacA  != null ? loFacA  : loFacB;
+            final String loName = loNameA != null ? loNameA : loNameB;
 
-            String upFac  = upFacA  != null ? upFacA  : upFacB;
-            String upName = upNameA != null ? upNameA : upNameB;
+            final String upFac  = upFacA  != null ? upFacA  : upFacB;
+            final String upName = upNameA != null ? upNameA : upNameB;
 
-            String loMainValue = loFac + " " + loName;
-            String upMainValue = upFac + " " + upName;
+            final String loMainValue = loFac + " " + loName;
+            final String upMainValue = upFac + " " + upName;
 
             return new Object[] { loMainValue, upMainValue };
         }
 
-        Matcher mE = META_MAINVALUE_E.matcher(mainValueStr.trim());
+        final Matcher mE = META_MAINVALUE_E.matcher(mainValueStr.trim());
         if (mE.matches()) {
             log.debug("mainValueStr matches META_MAINVALUE_E");
-            String lower = mE.group(1);
-            String upper = mE.group(4);
+            final String lower = mE.group(1);
+            final String upper = mE.group(4);
 
             return new Object[] { lower, upper };
         }
 
-    log.debug("mainValueStr not matched");
+        log.debug("mainValueStr not matched");
         return null;
     }
 
 
-    protected Object[] handleGaugeString(String gaugeStr) {
-        Matcher m = META_GAUGE.matcher(gaugeStr);
+    protected Object[] handleGaugeString(final String gaugeStr) {
+        final Matcher m = META_GAUGE.matcher(gaugeStr);
 
         if (m.matches()) {
-            String name = m.group(1);
-            String qStr = m.group(2);
+            final String name = m.group(1);
+            final String qStr = m.group(2);
 
             try {
                 return new Object[] {
-                    name,
-                    new BigDecimal(nf.parse(qStr).doubleValue()) };
+                        name,
+                        AbstractParser.parseDecimal(qStr) };
             }
-            catch (ParseException pe) {
+            catch (final NumberFormatException pe) {
                 log.warn("Could not parse Q value: '" + qStr + "'");
             }
         }
@@ -246,8 +244,8 @@
     }
 
 
-    protected void handleDataLine(String line) {
-        String[] cols = line.split(SEPERATOR_CHAR);
+    protected void handleDataLine(final String line) {
+        final String[] cols = line.split(SEPERATOR_CHAR);
 
         if (cols.length < 5) {
             log.warn("skip invalid data line: '" + line + "'");
@@ -255,31 +253,25 @@
         }
 
         try {
-            double km = nf.parse(cols[0]).doubleValue();
+            final BigDecimal km = AbstractParser.parseDecimal(cols[0]);
 
-            Double key = Double.valueOf(km);
+            final Double key = Double.valueOf(km.doubleValue());
 
-            if (kmExists.contains(key)) {
+            if (this.kmExists.contains(key)) {
                 log.warn("duplicate station '" + km + "': -> ignored");
                 return;
             }
 
-            double q      = nf.parse(cols[1]).doubleValue();
-            double total  = nf.parse(cols[2]).doubleValue();
-            double main   = nf.parse(cols[3]).doubleValue();
-            double stress = nf.parse(cols[4]).doubleValue();
+            final BigDecimal q = AbstractParser.parseDecimal(cols[1]);
+            final BigDecimal total = AbstractParser.parseDecimal(cols[2]);
+            final BigDecimal main = AbstractParser.parseDecimal(cols[3]);
+            final BigDecimal stress = AbstractParser.parseDecimal(cols[4]);
 
-            current.addValue(new ImportFlowVelocityModelValue(
-                new BigDecimal(km),
-                new BigDecimal(q),
-                new BigDecimal(total),
-                new BigDecimal(main),
-                new BigDecimal(stress)
-            ));
+            this.current.addValue(new ImportFlowVelocityModelValue(km, q, total, main, stress));
 
-            kmExists.add(key);
+            this.kmExists.add(key);
         }
-        catch (ParseException pe) {
+        catch (final NumberFormatException pe) {
             log.warn("Unparseable flow velocity values:", pe);
         }
     }
--- a/backend/src/main/java/org/dive4elements/river/importer/parsers/MeasurementStationsParser.java	Sun Apr 08 18:09:32 2018 +0200
+++ b/backend/src/main/java/org/dive4elements/river/importer/parsers/MeasurementStationsParser.java	Mon Apr 09 09:07:00 2018 +0200
@@ -8,19 +8,17 @@
 
 package org.dive4elements.river.importer.parsers;
 
-import java.math.BigDecimal;
 import java.text.ParseException;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 
 import org.apache.log4j.Logger;
-
-import org.dive4elements.river.model.MeasurementStation;
-
 import org.dive4elements.river.importer.ImportMeasurementStation;
 import org.dive4elements.river.importer.ImportRange;
 import org.dive4elements.river.importer.ImportTimeInterval;
+import org.dive4elements.river.importer.common.AbstractParser;
+import org.dive4elements.river.model.MeasurementStation;
 
 
 public class MeasurementStationsParser extends LineParser {
@@ -29,7 +27,7 @@
 
         private static final long serialVersionUID = 1L;
 
-        public MeasurementStationParserException(String msg) {
+        public MeasurementStationParserException(final String msg) {
             super(msg);
         }
     }
@@ -39,14 +37,14 @@
     public static final int MAX_COMMENT_LENGTH = 512;
 
     private static final Logger log = Logger
-        .getLogger(MeasurementStationsParser.class);
+            .getLogger(MeasurementStationsParser.class);
 
     private List<ImportMeasurementStation> measurementStations;
     private ImportMeasurementStation current;
 
     @Override
     protected void reset() {
-        this.measurementStations = new ArrayList<ImportMeasurementStation>();
+        this.measurementStations = new ArrayList<>();
     }
 
     @Override
@@ -54,114 +52,109 @@
     }
 
     @Override
-    protected void handleLine(int lineNum, String line) {
+    protected void handleLine(final int lineNum, final String line) {
         if (line == null || line.startsWith(START_META_CHAR)) {
             log.info("skip meta information at line " + lineNum);
             return;
         }
 
         try {
-            current = new ImportMeasurementStation();
+            this.current = new ImportMeasurementStation();
             handleDataLine(lineNum, line);
-            measurementStations.add(current);
+            this.measurementStations.add(this.current);
         }
-        catch (MeasurementStationParserException e) {
+        catch (final MeasurementStationParserException e) {
             log.warn("Problem in line " + lineNum + ": " + e.getMessage());
         }
     }
 
     public List<ImportMeasurementStation> getMeasurementStations() {
-        return measurementStations;
+        return this.measurementStations;
     }
 
-    protected void handleDataLine(int lineNum, String line)
-        throws MeasurementStationParserException {
-        String[] cols = line.split(SEPERATOR_CHAR);
+    protected void handleDataLine(final int lineNum, final String line)
+            throws MeasurementStationParserException {
+        final String[] cols = line.split(SEPERATOR_CHAR);
 
         if (cols == null || cols.length < MIN_COLUMNS) {
-            int num = cols != null ? cols.length : 0;
+            final int num = cols != null ? cols.length : 0;
             throw new MeasurementStationParserException("Not enough columns: "
-                + num);
+                    + num);
         }
 
-        current.name = getName(cols, lineNum);
-        current.range = getRange(cols, lineNum);
-        current.measurementType = getMeasurementType(cols, lineNum);
-        current.riverside = getRiverside(cols, lineNum);
-        current.gauge = getGauge(cols, lineNum);
-        current.observationTimerange = getObservationTimerange(cols, lineNum);
-        current.operator = getOperator(cols, lineNum);
-        current.comment = getComment(cols, lineNum);
+        this.current.name = getName(cols, lineNum);
+        this.current.range = getRange(cols, lineNum);
+        this.current.measurementType = getMeasurementType(cols, lineNum);
+        this.current.riverside = getRiverside(cols, lineNum);
+        this.current.gauge = getGauge(cols, lineNum);
+        this.current.observationTimerange = getObservationTimerange(cols, lineNum);
+        this.current.operator = getOperator(cols, lineNum);
+        this.current.comment = getComment(cols, lineNum);
     }
 
-    protected String getName(String[] cols, int lineNum)
-        throws MeasurementStationParserException {
+    protected String getName(final String[] cols, final int lineNum)
+            throws MeasurementStationParserException {
         if (cols[0] == null || cols[0].length() == 0) {
             throw new MeasurementStationParserException("invalid name in line "
-                + lineNum);
+                    + lineNum);
         }
 
         return cols[0];
     }
 
-    protected ImportRange getRange(String[] cols, int lineNum) {
-        String from = cols[1];
-        String to   = cols[4];
+    protected ImportRange getRange(final String[] cols, final int lineNum) {
+        final String from = cols[1];
+        final String to   = cols[4];
         if (from == null || from.length() == 0) {
             log.error("No station found in line" + lineNum);
             return null;
         }
 
         try {
-            double lower = getDouble(from);
-
             if (to == null || to.length() == 0) {
                 log.warn("No end km found in line " + lineNum);
-                return new ImportRange(new BigDecimal(lower));
+                return new ImportRange(AbstractParser.parseDecimal(from));
             }
 
             try {
-                double upper = getDouble(to);
-
-                return new ImportRange(new BigDecimal(lower),
-                    new BigDecimal(upper));
+                return new ImportRange(AbstractParser.parseDecimal(from), AbstractParser.parseDecimal(to));
             }
-            catch (ParseException e) {
+            catch (final NumberFormatException e) {
                 log.warn("Unparseable end km in line " + lineNum +
-                    ". Error: " + e.getMessage());
-                return new ImportRange(new BigDecimal(lower));
+                        ". Error: " + e.getMessage());
+                return new ImportRange(AbstractParser.parseDecimal(from));
             }
 
         }
-        catch (ParseException e) {
+        catch (final NumberFormatException e) {
             log.error("Unparseable station in line " + lineNum +
                     ". Error: " + e.getMessage());
             return null;
         }
     }
 
-    protected String getMeasurementType(String[] cols, int lineNum)
-        throws MeasurementStationParserException {
-        String mtype = cols[2].trim();
+    protected String getMeasurementType(final String[] cols, final int lineNum)
+            throws MeasurementStationParserException {
+        final String mtype = cols[2].trim();
         if (!(MeasurementStation.MEASUREMENT_TYPE_BEDLOAD.equals(mtype) ||
                 MeasurementStation.MEASUREMENT_TYPE_SUSP.equals(mtype))) {
             throw new MeasurementStationParserException(
-                "invalid measurement type in line " + lineNum);
+                    "invalid measurement type in line " + lineNum);
         }
 
         return mtype;
     }
 
-    protected String getRiverside(String[] cols, int lineNum) {
-        String col = cols[3];
+    protected String getRiverside(final String[] cols, final int lineNum) {
+        final String col = cols[3];
         if (col == null || col.length() == 0) {
             log.warn("No river side given in line " + lineNum);
         }
         return col;
     }
 
-    protected String getGauge(String[] cols, int lineNum) {
-        String col = cols[5];
+    protected String getGauge(final String[] cols, final int lineNum) {
+        final String col = cols[5];
         if (col == null || col.length() == 0) {
             log.warn("Invalid gauge found in line " + lineNum);
         }
@@ -169,45 +162,45 @@
     }
 
     protected ImportTimeInterval getObservationTimerange(
-        String[] cols,
-        int lineNum
-    ) {
-        String col = cols[7];
+            final String[] cols,
+            final int lineNum
+            ) {
+        final String col = cols[7];
         if (col == null || col.length() == 0) {
             log.warn("Observation time invalid in line " + lineNum);
             return null;
         }
 
         try {
-            Date date = getDate(col);
+            final Date date = getDate(col);
 
             if (date != null) {
                 return new ImportTimeInterval(date);
             }
             log.warn("Observation time invalid in line " + lineNum);
         }
-        catch (ParseException pe) {
+        catch (final ParseException pe) {
             log.warn("Unparseable observation time '" + col +
-                "' in line " + lineNum);
+                    "' in line " + lineNum);
         }
         return null;
     }
 
-    protected String getOperator(String[] cols, int lineNum) {
-        String col = cols[8];
+    protected String getOperator(final String[] cols, final int lineNum) {
+        final String col = cols[8];
         if (col == null || col.length() == 0) {
             log.warn("No operator given in line " + lineNum);
         }
         return col;
     }
 
-    protected String getComment(String[] cols, int lineNum) {
+    protected String getComment(final String[] cols, final int lineNum) {
         if (cols.length > MIN_COLUMNS) {
-            String col = cols[9];
+            final String col = cols[9];
             if (col.length() > MAX_COMMENT_LENGTH) {
                 log.warn("Comment in line " + lineNum +
-                    " longer than allowed " + MAX_COMMENT_LENGTH +
-                    " characters. Truncated.");
+                        " longer than allowed " + MAX_COMMENT_LENGTH +
+                        " characters. Truncated.");
                 return col.substring(0, MAX_COMMENT_LENGTH);
             }
             return col;
--- a/backend/src/main/java/org/dive4elements/river/importer/parsers/MorphologicalWidthParser.java	Sun Apr 08 18:09:32 2018 +0200
+++ b/backend/src/main/java/org/dive4elements/river/importer/parsers/MorphologicalWidthParser.java	Mon Apr 09 09:07:00 2018 +0200
@@ -9,32 +9,29 @@
 package org.dive4elements.river.importer.parsers;
 
 import java.math.BigDecimal;
-
 import java.text.NumberFormat;
-import java.text.ParseException;
-
 import java.util.ArrayList;
 import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import org.apache.log4j.Logger;
-
 import org.dive4elements.river.importer.ImportMorphWidth;
 import org.dive4elements.river.importer.ImportMorphWidthValue;
 import org.dive4elements.river.importer.ImportUnit;
+import org.dive4elements.river.importer.common.AbstractParser;
 
 
 public class MorphologicalWidthParser extends LineParser {
 
     private static final Logger log =
-        Logger.getLogger(MorphologicalWidthParser.class);
+            Logger.getLogger(MorphologicalWidthParser.class);
 
     public static final NumberFormat nf = NumberFormat.getInstance(
-        DEFAULT_LOCALE);
+            DEFAULT_LOCALE);
 
     public static final Pattern META_UNIT =
-        Pattern.compile("^Einheit: \\[(.*)\\].*");
+            Pattern.compile("^Einheit: \\[(.*)\\].*");
 
     protected List<ImportMorphWidth> morphWidths;
 
@@ -42,26 +39,26 @@
 
 
     public MorphologicalWidthParser() {
-        morphWidths = new ArrayList<ImportMorphWidth>();
+        this.morphWidths = new ArrayList<>();
     }
 
 
     @Override
     protected void reset() {
-        current = new ImportMorphWidth();
+        this.current = new ImportMorphWidth();
     }
 
 
     @Override
     protected void finish() {
-        if (current != null) {
-            morphWidths.add(current);
+        if (this.current != null) {
+            this.morphWidths.add(this.current);
         }
     }
 
 
     @Override
-    protected void handleLine(int lineNum, String line) {
+    protected void handleLine(final int lineNum, final String line) {
         if (line.startsWith(START_META_CHAR)) {
             handleMetaLine(stripMetaLine(line));
         }
@@ -71,7 +68,7 @@
     }
 
 
-    protected void handleMetaLine(String line) {
+    protected void handleMetaLine(final String line) {
         if (handleMetaUnit(line)) {
             return;
         }
@@ -81,13 +78,13 @@
     }
 
 
-    protected boolean handleMetaUnit(String line) {
-        Matcher m = META_UNIT.matcher(line);
+    protected boolean handleMetaUnit(final String line) {
+        final Matcher m = META_UNIT.matcher(line);
 
         if (m.matches()) {
-            String unit = m.group(1);
+            final String unit = m.group(1);
 
-            current.setUnit(new ImportUnit(unit));
+            this.current.setUnit(new ImportUnit(unit));
 
             return true;
         }
@@ -96,8 +93,8 @@
     }
 
 
-    protected void handleDataLine(String line) {
-        String[] vals = line.split(SEPERATOR_CHAR);
+    protected void handleDataLine(final String line) {
+        final String[] vals = line.split(SEPERATOR_CHAR);
 
         if (vals == null || vals.length < 2) {
             log.warn("MWP: skip invalid data line: '" + line + "'");
@@ -105,25 +102,25 @@
         }
 
         try {
-            BigDecimal km    = new BigDecimal(nf.parse(vals[0]).doubleValue());
-            BigDecimal width = new BigDecimal(nf.parse(vals[1]).doubleValue());
-
-            String desc = vals.length > 2 ? vals[2] : null;
+            final BigDecimal km = AbstractParser.parseDecimal(vals[0]);
+            final BigDecimal width = AbstractParser.parseDecimal(vals[1]);
 
-            current.addValue(new ImportMorphWidthValue(
-                km,
-                width,
-                desc
-            ));
+            final String desc = vals.length > 2 ? vals[2] : null;
+
+            this.current.addValue(new ImportMorphWidthValue(
+                    km,
+                    width,
+                    desc
+                    ));
         }
-        catch (ParseException pe) {
+        catch (final NumberFormatException pe) {
             log.warn("MWP: unparseable number in data row: " + line);
         }
     }
 
 
     public List<ImportMorphWidth> getMorphologicalWidths() {
-        return morphWidths;
+        return this.morphWidths;
     }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/backend/src/main/java/org/dive4elements/river/importer/parsers/SedimentDensityParser.java	Sun Apr 08 18:09:32 2018 +0200
+++ b/backend/src/main/java/org/dive4elements/river/importer/parsers/SedimentDensityParser.java	Mon Apr 09 09:07:00 2018 +0200
@@ -8,39 +8,34 @@
 
 package org.dive4elements.river.importer.parsers;
 
-import org.dive4elements.river.importer.ImportDepth;
-import org.dive4elements.river.importer.ImportSedimentDensity;
-import org.dive4elements.river.importer.ImportSedimentDensityValue;
-
 import java.io.File;
 import java.io.IOException;
-
 import java.math.BigDecimal;
-
 import java.text.NumberFormat;
-import java.text.ParseException;
-
 import java.util.ArrayList;
 import java.util.List;
-
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import org.apache.log4j.Logger;
+import org.dive4elements.river.importer.ImportDepth;
+import org.dive4elements.river.importer.ImportSedimentDensity;
+import org.dive4elements.river.importer.ImportSedimentDensityValue;
+import org.dive4elements.river.importer.common.AbstractParser;
 
 public class SedimentDensityParser extends LineParser {
 
     private static final Logger log =
-        Logger.getLogger(SedimentDensityParser.class);
+            Logger.getLogger(SedimentDensityParser.class);
 
     public static final NumberFormat nf =
-        NumberFormat.getInstance(DEFAULT_LOCALE);
+            NumberFormat.getInstance(DEFAULT_LOCALE);
 
     public static final Pattern META_DEPTH =
-        Pattern.compile("^Tiefe: (\\d++)-(\\d++).*");
+            Pattern.compile("^Tiefe: (\\d++)-(\\d++).*");
 
     public static final Pattern META_YEAR =
-        Pattern.compile("^Jahr: (\\d{4}).*");
+            Pattern.compile("^Jahr: (\\d{4}).*");
 
     protected List<ImportSedimentDensity> sedimentDensities;
 
@@ -51,13 +46,13 @@
     protected String yearString;
 
     public SedimentDensityParser() {
-        sedimentDensities = new ArrayList<ImportSedimentDensity>();
+        this.sedimentDensities = new ArrayList<>();
     }
 
 
     @Override
-    public void parse(File file) throws IOException {
-        currentDescription = file.getName();
+    public void parse(final File file) throws IOException {
+        this.currentDescription = file.getName();
 
         super.parse(file);
     }
@@ -65,20 +60,20 @@
 
     @Override
     protected void reset() {
-        current = new ImportSedimentDensity(currentDescription);
+        this.current = new ImportSedimentDensity(this.currentDescription);
     }
 
 
     @Override
     protected void finish() {
-        if (current != null) {
-            sedimentDensities.add(current);
+        if (this.current != null) {
+            this.sedimentDensities.add(this.current);
         }
     }
 
 
     @Override
-    protected void handleLine(int lineNum, String line) {
+    protected void handleLine(final int lineNum, final String line) {
         if (line.startsWith(START_META_CHAR)) {
             handleMetaLine(stripMetaLine(line));
         }
@@ -88,7 +83,7 @@
     }
 
 
-    protected void handleMetaLine(String line) {
+    protected void handleMetaLine(final String line) {
         if (handleMetaDepth(line)) {
             return;
         }
@@ -99,27 +94,26 @@
     }
 
 
-    protected boolean handleMetaDepth(String line) {
-        Matcher m = META_DEPTH.matcher(line);
+    protected boolean handleMetaDepth(final String line) {
+        final Matcher m = META_DEPTH.matcher(line);
 
         if (m.matches()) {
-            String lo   = m.group(1);
-            String up   = m.group(2);
+            final String lo   = m.group(1);
+            final String up   = m.group(2);
 
             log.info("Found sediment density depth: "
-                + lo + " - " + up + " cm");
+                    + lo + " - " + up + " cm");
 
             try {
-                ImportDepth depth = new ImportDepth(
-                    new BigDecimal(nf.parse(lo).doubleValue()),
-                    new BigDecimal(nf.parse(up).doubleValue())
-                );
+                final ImportDepth depth = new ImportDepth(
+                        AbstractParser.parseDecimal(lo),
+                        AbstractParser.parseDecimal(up));
 
-                current.setDepth(depth);
+                this.current.setDepth(depth);
 
                 return true;
             }
-            catch (ParseException pe) {
+            catch (final NumberFormatException pe) {
                 log.warn("Unparseable numbers in: '" + line + "'");
             }
         }
@@ -130,13 +124,13 @@
         return false;
     }
 
-    protected boolean handleMetaYear(String line) {
-        Matcher m = META_YEAR.matcher(line);
+    protected boolean handleMetaYear(final String line) {
+        final Matcher m = META_YEAR.matcher(line);
 
         if (m.matches()) {
-            yearString = m.group(1);
+            this.yearString = m.group(1);
 
-            log.info("Found sediment density year: " + yearString);
+            log.info("Found sediment density year: " + this.yearString);
 
             return true;
         }
@@ -147,8 +141,8 @@
     }
 
 
-    protected void handleDataLine(String line) {
-        String[] vals = line.split(SEPERATOR_CHAR);
+    protected void handleDataLine(final String line) {
+        final String[] vals = line.split(SEPERATOR_CHAR);
 
         if (vals == null || vals.length < 3) {
             log.warn("skip invalid data line: '" + line + "'");
@@ -159,13 +153,13 @@
         BigDecimal shoreOffset = null;
         BigDecimal density = null;
         try {
-            km          = new BigDecimal(nf.parse(vals[0]).doubleValue());
-            density     = new BigDecimal(nf.parse(vals[2]).doubleValue());
+            km = AbstractParser.parseDecimal(vals[0]);
+            density = AbstractParser.parseDecimal(vals[2]);
             if (!vals[1].isEmpty()) {
-                shoreOffset = new BigDecimal(nf.parse(vals[1]).doubleValue());
+                shoreOffset = AbstractParser.parseDecimal(vals[1]);
             }
         }
-        catch (ParseException pe) {
+        catch (final NumberFormatException pe) {
             log.warn("Unparseable numbers in '" + line + "'");
         }
 
@@ -175,26 +169,26 @@
         }
 
         BigDecimal year = null;
-        if (yearString != null) {
+        if (this.yearString != null) {
             try {
-                year = new BigDecimal(nf.parse(yearString).doubleValue());
+                year = AbstractParser.parseDecimal(this.yearString);
             }
-            catch (ParseException pe) {
+            catch (final NumberFormatException pe) {
                 log.warn("Unparseable year string");
             }
         }
 
-        current.addValue(new ImportSedimentDensityValue(
-            km,
-            shoreOffset,
-            density,
-            year,
-            currentDescription));
+        this.current.addValue(new ImportSedimentDensityValue(
+                km,
+                shoreOffset,
+                density,
+                year,
+                this.currentDescription));
     }
 
 
     public List<ImportSedimentDensity> getSedimentDensities() {
-        return sedimentDensities;
+        return this.sedimentDensities;
     }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/backend/src/main/java/org/dive4elements/river/importer/parsers/WaterlevelDifferencesParser.java	Sun Apr 08 18:09:32 2018 +0200
+++ b/backend/src/main/java/org/dive4elements/river/importer/parsers/WaterlevelDifferencesParser.java	Mon Apr 09 09:07:00 2018 +0200
@@ -12,22 +12,20 @@
 import java.io.IOException;
 import java.math.BigDecimal;
 import java.text.NumberFormat;
-import java.text.ParseException;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import org.apache.log4j.Logger;
-
+import org.dive4elements.river.backend.utils.DateUtil;
 import org.dive4elements.river.importer.ImportTimeInterval;
 import org.dive4elements.river.importer.ImportUnit;
-
 import org.dive4elements.river.importer.ImportWst;
-import org.dive4elements.river.importer.ImportWstQRange;
 import org.dive4elements.river.importer.ImportWstColumn;
 import org.dive4elements.river.importer.ImportWstColumnValue;
-import org.dive4elements.river.backend.utils.DateUtil;
+import org.dive4elements.river.importer.ImportWstQRange;
+import org.dive4elements.river.importer.common.AbstractParser;
 
 
 /**
@@ -36,21 +34,21 @@
 public class WaterlevelDifferencesParser extends LineParser {
 
     private static final Logger log =
-        Logger.getLogger(WaterlevelDifferencesParser.class);
+            Logger.getLogger(WaterlevelDifferencesParser.class);
 
     private static final NumberFormat nf =
-        NumberFormat.getInstance(DEFAULT_LOCALE);
+            NumberFormat.getInstance(DEFAULT_LOCALE);
 
     public static final Pattern META_UNIT =
-        Pattern.compile("^Einheit: \\[(.*)\\].*");
+            Pattern.compile("^Einheit: \\[(.*)\\].*");
 
     public static final Pattern YEARS_IN_COLUMN =
-        Pattern.compile(".*(\\d{4})-(\\d{4})$");
+            Pattern.compile(".*(\\d{4})-(\\d{4})$");
 
-    public static final double INTERVAL_GAP = 0.00001d;
+    public static final BigDecimal INTERVAL_GAP = new BigDecimal("0.00001");
 
     /** List of parsed differences as ImportWst s. */
-    private List<ImportWst> differences;
+    private final List<ImportWst> differences;
 
     private ImportWstColumn[] columns;
 
@@ -59,13 +57,13 @@
 
 
     public WaterlevelDifferencesParser() {
-        differences = new ArrayList<ImportWst>();
+        this.differences = new ArrayList<>();
     }
 
 
     /** Get the differences as wst parsed so far. */
     public List<ImportWst> getDifferences() {
-        return differences;
+        return this.differences;
     }
 
 
@@ -74,9 +72,9 @@
      * from it.
      */
     @Override
-    public void parse(File file) throws IOException {
-        current = new ImportWst(file.getName());
-        current.setKind(6);
+    public void parse(final File file) throws IOException {
+        this.current = new ImportWst(file.getName());
+        this.current.setKind(6);
 
         super.parse(file);
     }
@@ -90,14 +88,14 @@
 
     @Override
     protected void finish() {
-        if (columns != null && current != null) {
+        if (this.columns != null && this.current != null) {
             // TODO figure out if its needed, as the columns
             //      are registered at their construction time.
-            for (ImportWstColumn col: columns) {
+            for (final ImportWstColumn col: this.columns) {
                 // TODO place a current.addColumn(col); here?
             }
 
-            differences.add(current);
+            this.differences.add(this.current);
         }
 
         // For all differences columns, add a single Q-Range with
@@ -106,27 +104,27 @@
         // TODO: should otherwise be extended to
         // (first station of next range - INTERVAL_GAP),
         // assuming always ascending stations
-        for (ImportWstColumn column: columns) {
-            List<ImportWstColumnValue> cValues = column.getColumnValues();
-            BigDecimal a = cValues.get(0).getPosition();
+        for (final ImportWstColumn column: this.columns) {
+            final List<ImportWstColumnValue> cValues = column.getColumnValues();
+            final BigDecimal a = cValues.get(0).getPosition();
             BigDecimal b = cValues.get(cValues.size() - 1).getPosition();
             if (a.compareTo(b) == 0) {
-                b = new BigDecimal(b.doubleValue() + INTERVAL_GAP);
+                b = b.add(INTERVAL_GAP);
             }
             column.addColumnQRange(
-                new ImportWstQRange(
-                    a,
-                    b,
-                    new BigDecimal(-1d))
-                );
+                    new ImportWstQRange(
+                            a,
+                            b,
+                            new BigDecimal(-1d))
+                    );
         }
-        current = null;
-        columns = null;
+        this.current = null;
+        this.columns = null;
     }
 
 
     @Override
-    protected void handleLine(int lineNum, String line) {
+    protected void handleLine(final int lineNum, final String line) {
         if (line.startsWith(START_META_CHAR)) {
             handleMetaLine(stripMetaLine(line));
         }
@@ -136,7 +134,7 @@
     }
 
 
-    private void handleMetaLine(String meta) {
+    private void handleMetaLine(final String meta) {
         if (handleMetaUnit(meta)) {
             return;
         }
@@ -146,14 +144,14 @@
     }
 
 
-    private boolean handleMetaUnit(String meta) {
-        Matcher m = META_UNIT.matcher(meta);
+    private boolean handleMetaUnit(final String meta) {
+        final Matcher m = META_UNIT.matcher(meta);
 
         if (m.matches()) {
-            String unit = m.group(1);
+            final String unit = m.group(1);
             log.debug("Found unit: '" + unit + "'");
 
-            current.setUnit(new ImportUnit(unit));
+            this.current.setUnit(new ImportUnit(unit));
 
             return true;
         }
@@ -162,13 +160,13 @@
     }
 
 
-    private boolean handleMetaColumnNames(String meta) {
-        Pattern META_COLUMN_NAMES = Pattern.compile("Fluss-km;(.*)");
-        Matcher m = META_COLUMN_NAMES.matcher(meta);
+    private boolean handleMetaColumnNames(final String meta) {
+        final Pattern META_COLUMN_NAMES = Pattern.compile("Fluss-km;(.*)");
+        final Matcher m = META_COLUMN_NAMES.matcher(meta);
 
         if (m.matches()) {
-            String colStr = m.group(1);
-            String[] cols = colStr.split(SEPERATOR_CHAR);
+            final String colStr = m.group(1);
+            final String[] cols = colStr.split(SEPERATOR_CHAR);
 
             log.debug("Found " + cols.length + " columns.");
 
@@ -182,28 +180,28 @@
 
 
     /** Setup column structures with name, description and time interval. */
-    private void initColumns(String[] cols) {
-        current.setNumberColumns(cols.length);
-        columns = current.getColumns().toArray(
-            new ImportWstColumn[cols.length]);
+    private void initColumns(final String[] cols) {
+        this.current.setNumberColumns(cols.length);
+        this.columns = this.current.getColumns().toArray(
+                new ImportWstColumn[cols.length]);
 
         for (int i = 0; i < cols.length; i++) {
-            String name = cols[i].replace("\"", "");
+            final String name = cols[i].replace("\"", "");
 
             log.debug("Create new column '" + name + "'");
-            ImportWstColumn column = current.getColumn(i);
+            final ImportWstColumn column = this.current.getColumn(i);
             column.setName(name);
             column.setDescription(name);
 
-            Matcher m = YEARS_IN_COLUMN.matcher(name);
+            final Matcher m = YEARS_IN_COLUMN.matcher(name);
 
             if (m.matches()) {
-                int startYear = Integer.parseInt(m.group(1));
-                int endYear   = Integer.parseInt(m.group(2));
-                ImportTimeInterval time = new ImportTimeInterval(
-                    DateUtil.getStartDateFromYear(startYear),
-                    DateUtil.getEndDateFromYear(endYear)
-                );
+                final int startYear = Integer.parseInt(m.group(1));
+                final int endYear   = Integer.parseInt(m.group(2));
+                final ImportTimeInterval time = new ImportTimeInterval(
+                        DateUtil.getStartDateFromYear(startYear),
+                        DateUtil.getEndDateFromYear(endYear)
+                        );
                 column.setTimeInterval(time);
             } else {
                 log.debug("No time interval in column header found: " + name);
@@ -215,9 +213,9 @@
     /** Handle one line of data, add one value for all columns.
      * @param line the line to parse
      */
-    private void handleDataLine(String line) {
+    private void handleDataLine(final String line) {
         // Split by separator, do not exclude trailing empty string.
-        String[] cols = line.split(SEPERATOR_CHAR, -1);
+        final String[] cols = line.split(SEPERATOR_CHAR, -1);
 
         if (cols == null || cols.length < 2) {
             log.warn("skip invalid waterlevel-diff line: '" + line + "'");
@@ -227,31 +225,31 @@
         try {
             // The first value in a line like 12,9;4,3;4,5 is the station,
             // later real values.
-            Double station = nf.parse(cols[0]).doubleValue();
+            final BigDecimal station = AbstractParser.parseDecimal(cols[0]);
 
-            for (int i = 0; i < columns.length; i++) {
-                int idx = i+1;
+            for (int i = 0; i < this.columns.length; i++) {
+                final int idx = i+1;
 
                 if (idx >= cols.length) {
                     log.warn("Insufficient column numbers: " + line);
                     continue;
                 }
 
-                String value = cols[idx];
+                final String value = cols[idx];
 
                 if (value != null && !value.equals("")) {
                     try {
-                        columns[i].addColumnValue(
-                            new BigDecimal(station),
-                            new BigDecimal(nf.parse(value).doubleValue()));
+                        this.columns[i].addColumnValue(
+                                station,
+                                AbstractParser.parseDecimal(value));
                     }
-                    catch (ParseException pe) {
+                    catch (final NumberFormatException pe) {
                         log.warn("Could not parse value: '" + value + "'");
                     }
                 }
             }
         }
-        catch (ParseException pe) {
+        catch (final NumberFormatException pe) {
             log.warn("Could not parse station: '" + line + "'");
         }
     }
--- a/backend/src/main/java/org/dive4elements/river/importer/parsers/WaterlevelParser.java	Sun Apr 08 18:09:32 2018 +0200
+++ b/backend/src/main/java/org/dive4elements/river/importer/parsers/WaterlevelParser.java	Mon Apr 09 09:07:00 2018 +0200
@@ -12,23 +12,21 @@
 import java.io.IOException;
 import java.math.BigDecimal;
 import java.text.NumberFormat;
-import java.text.ParseException;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import org.apache.log4j.Logger;
-
+import org.dive4elements.river.backend.utils.DateUtil;
+import org.dive4elements.river.importer.ImportRange;
 import org.dive4elements.river.importer.ImportTimeInterval;
 import org.dive4elements.river.importer.ImportUnit;
-
-import org.dive4elements.river.importer.ImportRange;
 import org.dive4elements.river.importer.ImportWst;
 import org.dive4elements.river.importer.ImportWstColumn;
 import org.dive4elements.river.importer.ImportWstColumnValue;
 import org.dive4elements.river.importer.ImportWstQRange;
-import org.dive4elements.river.backend.utils.DateUtil;
+import org.dive4elements.river.importer.common.AbstractParser;
 
 
 /**
@@ -43,17 +41,17 @@
     private static final Logger log = Logger.getLogger(WaterlevelParser.class);
 
     private static final NumberFormat nf =
-        NumberFormat.getInstance(DEFAULT_LOCALE);
+            NumberFormat.getInstance(DEFAULT_LOCALE);
 
     private static final Pattern META_Q_RANGE =
-        Pattern.compile("Abfluss\\s\\[(.*)\\];(.*)");
+            Pattern.compile("Abfluss\\s\\[(.*)\\];(.*)");
 
     public static final Pattern META_UNIT =
-        Pattern.compile("^Einheit: \\[(.*)\\].*");
+            Pattern.compile("^Einheit: \\[(.*)\\].*");
 
-    public static final double INTERVAL_GAP = 0.00001d;
+    public static final BigDecimal INTERVAL_GAP = new BigDecimal("0.00001");
 
-    private List<ImportWst> waterlevels;
+    private final List<ImportWst> waterlevels;
 
     private ImportWst current;
 
@@ -70,18 +68,18 @@
 
 
     public WaterlevelParser() {
-        waterlevels = new ArrayList<ImportWst>();
+        this.waterlevels = new ArrayList<>();
     }
 
 
     public List<ImportWst> getWaterlevels() {
-        return waterlevels;
+        return this.waterlevels;
     }
 
 
     @Override
-    public void parse(File file) throws IOException {
-        currentDescription = file.getName();
+    public void parse(final File file) throws IOException {
+        this.currentDescription = file.getName();
 
         super.parse(file);
     }
@@ -89,64 +87,63 @@
 
     @Override
     protected void reset() {
-        currentQRange = null;
-        current       = new ImportWst(currentDescription);
-        current.setNumberColumns(1);
-        column        = current.getColumn(0);
-        column.setName(currentDescription);
-        column.setDescription(currentDescription);
+        this.currentQRange = null;
+        this.current       = new ImportWst(this.currentDescription);
+        this.current.setNumberColumns(1);
+        this.column        = this.current.getColumn(0);
+        this.column.setName(this.currentDescription);
+        this.column.setDescription(this.currentDescription);
 
         // Try to extract and set the TimeInterval.
-        Matcher m = WaterlevelDifferencesParser.YEARS_IN_COLUMN.matcher(
-            currentDescription);
+        final Matcher m = WaterlevelDifferencesParser.YEARS_IN_COLUMN.matcher(
+                this.currentDescription);
 
         if (m.matches()) {
-            int startYear = Integer.parseInt(m.group(1));
-            int endYear   = Integer.parseInt(m.group(2));
-            ImportTimeInterval time = new ImportTimeInterval(
-                DateUtil.getStartDateFromYear(startYear),
-                DateUtil.getEndDateFromYear(endYear)
-            );
-            column.setTimeInterval(time);
+            final int startYear = Integer.parseInt(m.group(1));
+            final int endYear   = Integer.parseInt(m.group(2));
+            final ImportTimeInterval time = new ImportTimeInterval(
+                    DateUtil.getStartDateFromYear(startYear),
+                    DateUtil.getEndDateFromYear(endYear)
+                    );
+            this.column.setTimeInterval(time);
         } else {
             log.debug("No time interval in column header found: "
-                + currentDescription);
+                    + this.currentDescription);
         }
 
-        current.setKind(7);
+        this.current.setKind(7);
     }
 
 
     @Override
     protected void finish() {
-        if (current != null) {
-            if (currentQRange != null) {
-                List<ImportWstColumnValue> cValues = column.getColumnValues();
+        if (this.current != null) {
+            if (this.currentQRange != null) {
+                final List<ImportWstColumnValue> cValues = this.column.getColumnValues();
                 // Set end of range to last station
                 // or expand range to minimal length in case it would be 0
                 // TODO: should otherwise be extended to
                 // (first station of next range - INTERVAL_GAP),
                 // assuming always ascending stations
-                BigDecimal lastStation = cValues.get(cValues.size() -1)
-                    .getPosition();
-                if (lastStation.compareTo(currentRange.getA()) == 0) {
-                    currentRange.setB(new BigDecimal(lastStation.doubleValue()
-                        + INTERVAL_GAP));
+                final BigDecimal lastStation = cValues.get(cValues.size() -1)
+                        .getPosition();
+                if (lastStation.compareTo(this.currentRange.getA()) == 0) {
+                    this.currentRange.setB(lastStation.add(INTERVAL_GAP));
                 }
                 else {
-                    currentRange.setB(lastStation);
+                    this.currentRange.setB(lastStation);
                 }
 
-                currentQRange.setRange(currentRange);
-                column.addColumnQRange(currentQRange);
+                this.currentQRange.setRange(this.currentRange);
+                this.column.addColumnQRange(this.currentQRange);
             }
 
-            waterlevels.add(current);
+            this.waterlevels.add(this.current);
         }
     }
 
     @Override
-    protected void handleLine(int lineNum, String line) {
+    protected void handleLine(final int lineNum, final String line) {
         if (line.startsWith(START_META_CHAR)) {
             handleMetaLine(stripMetaLine(line));
             return;
@@ -161,44 +158,44 @@
     }
 
 
-    private void handleMetaLine(String meta) {
-        Matcher m = META_UNIT.matcher(meta);
+    private void handleMetaLine(final String meta) {
+        final Matcher m = META_UNIT.matcher(meta);
 
         if (m.matches()) {
-            String unit = m.group(1);
+            final String unit = m.group(1);
             log.debug("Found unit: '" + unit + "'");
 
-            current.setUnit(new ImportUnit(unit));
+            this.current.setUnit(new ImportUnit(unit));
         }
     }
 
 
-    private boolean handleQRange(String line) {
-        Matcher m = META_Q_RANGE.matcher(line);
+    private boolean handleQRange(final String line) {
+        final Matcher m = META_Q_RANGE.matcher(line);
 
         if (m.matches()) {
-            String unitStr  = m.group(1);
-            String valueStr = m.group(2);
+            final String unitStr  = m.group(1);
+            final String valueStr = m.group(2);
             try {
-                if (currentQRange != null) {
+                if (this.currentQRange != null) {
                     // Finish off the last one.
-                    List<ImportWstColumnValue> cValues = column
-                        .getColumnValues();
+                    final List<ImportWstColumnValue> cValues = this.column
+                            .getColumnValues();
                     // Set end of range to last station.
-                    currentRange.setB(cValues.get(cValues.size() -1)
-                        .getPosition());
-                    currentQRange.setRange(currentRange);
-                    column.addColumnQRange(currentQRange);
+                    this.currentRange.setB(cValues.get(cValues.size() -1)
+                            .getPosition());
+                    this.currentQRange.setRange(this.currentRange);
+                    this.column.addColumnQRange(this.currentQRange);
                 }
-                currentQRange = new ImportWstQRange(null,
-                    new BigDecimal(nf.parse(valueStr).doubleValue()));
-                currentRange = new ImportRange();
+                this.currentQRange = new ImportWstQRange(null,
+                        AbstractParser.parseDecimal(valueStr));
+                this.currentRange = new ImportRange();
 
                 log.debug("Found new Q range: Q=" + valueStr);
 
                 return true;
             }
-            catch (ParseException pe) {
+            catch (final NumberFormatException pe) {
                 log.warn("Unparseable Q range: '" + line + "'");
             }
         }
@@ -207,8 +204,8 @@
     }
 
 
-    private void handleDataLine(String line) {
-        String[] cols = line.split(SEPERATOR_CHAR);
+    private void handleDataLine(final String line) {
+        final String[] cols = line.split(SEPERATOR_CHAR);
 
         if (cols == null || cols.length < 2) {
             log.warn("skip invalid waterlevel line: '" + line + "'");
@@ -217,18 +214,16 @@
 
         try {
             // Store the value and remember the position for QRange, if needed.
-            Double station = nf.parse(cols[0]).doubleValue();
-            Double value   = nf.parse(cols[1]).doubleValue();
+            final BigDecimal station = AbstractParser.parseDecimal(cols[0]);
+            final BigDecimal value = AbstractParser.parseDecimal(cols[1]);
 
-            BigDecimal stationBD = new BigDecimal(station);
+            this.column.addColumnValue(station, value);
 
-            column.addColumnValue(stationBD, new BigDecimal(value));
-
-            if (currentRange.getA() == null) {
-                currentRange.setA(stationBD);
+            if (this.currentRange.getA() == null) {
+                this.currentRange.setA(station);
             }
         }
-        catch (ParseException pe) {
+        catch (final NumberFormatException pe) {
             log.warn("Unparseable number in data row: " + line);
         }
     }

http://dive4elements.wald.intevation.org