diff backend/src/main/java/org/dive4elements/river/importer/uinfo/parsers/VegetationParser.java @ 9661:9b8ba3b83a15

Importer (s/u-info) vegetation zones: new database column in vegetation_type table for german type name, localized vegetation type names by querying the database instead of translating by resource property, detecting and cancelling the import of a second vegetation zone file for a river, detecting, logging, cancelling in case of wrong column titles, detecting, logging and ignoring lines with missing (color) values, comparing vegetation zone name and class with the database and logging+ignoring in case of inconsistencies, starting the most elevated zone with 0 instead of -1 overflow days
author mschaefer
date Mon, 23 Mar 2020 16:38:12 +0100
parents 6146358c4842
children
line wrap: on
line diff
--- a/backend/src/main/java/org/dive4elements/river/importer/uinfo/parsers/VegetationParser.java	Mon Mar 23 15:40:12 2020 +0100
+++ b/backend/src/main/java/org/dive4elements/river/importer/uinfo/parsers/VegetationParser.java	Mon Mar 23 16:38:12 2020 +0100
@@ -14,18 +14,22 @@
 import java.util.ArrayList;
 import java.util.EnumMap;
 import java.util.List;
+import java.util.Locale;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import org.apache.log4j.Logger;
 import org.dive4elements.river.importer.Config;
 import org.dive4elements.river.importer.ImportRiver;
+import org.dive4elements.river.importer.ImporterSession;
 import org.dive4elements.river.importer.common.AbstractParser;
 import org.dive4elements.river.importer.common.ParsingState;
 import org.dive4elements.river.importer.uinfo.importitem.VegetationSeriesImport;
 import org.dive4elements.river.importer.uinfo.importitem.VegetationZoneImport;
 import org.dive4elements.river.model.uinfo.Vegetation;
+import org.dive4elements.river.model.uinfo.VegetationType;
 import org.dive4elements.river.model.uinfo.VegetationZone;
+import org.hibernate.Session;
 
 /**
  * Reads and parses a vegetation zones file
@@ -39,6 +43,10 @@
 
     private static final Logger log = Logger.getLogger(VegetationParser.class);
 
+    private static final String IMPORT_FILENAME = "Standardvegetationszonen.csv";
+
+    private static final Pattern META_FIRST = Pattern.compile("^#\\sVegetationszonen.*", Pattern.CASE_INSENSITIVE);
+
     private static final Pattern META_NAME = Pattern.compile("^#\\sEinteilung:\\s*([^;]*).*", Pattern.CASE_INSENSITIVE);
 
     private static final Pattern META_COLUMNTITLES = Pattern.compile("^#*\\s*Vegetationstyp\\s*;.+", Pattern.CASE_INSENSITIVE);
@@ -96,10 +104,9 @@
      */
     public static List<VegetationParser> createParsers(final File importDir, final File relativeDir, final ImportRiver river) {
         final List<VegetationParser> parsers = new ArrayList<>();
-        if (importDir.exists()) {
-            for (final File file : listFiles(importDir, ".csv"))
-                parsers.add(new VegetationParser(file, new File(relativeDir, file.getName()), river));
-        }
+        final File importFile = new File(importDir, IMPORT_FILENAME);
+        if (importFile.exists())
+            parsers.add(new VegetationParser(importFile, new File(relativeDir, IMPORT_FILENAME), river));
         return parsers;
     }
 
@@ -115,12 +122,23 @@
 
     @Override
     protected boolean handleMetaOther() {
-        if (handleMetaName())
+        if (handleMetaFirst())
+            return true;
+        else if (handleMetaName())
             return true;
         else
             return false;
     }
 
+    private boolean handleMetaFirst() {
+        final Matcher m = META_FIRST.matcher(this.currentLine);
+        if (m.matches()) {
+            this.metaPatternsMatched.add(META_FIRST);
+            return true;
+        }
+        return false;
+    }
+
     private boolean handleMetaName() {
         final Matcher m = META_NAME.matcher(this.currentLine);
         if (m.matches()) {
@@ -150,13 +168,22 @@
                 }
             }
         }
-        if ((this.cols.get(ColTitlePattern.OVERFLOW_LIMIT) < 0) || (this.cols.get(ColTitlePattern.CLASSNO) < 0)) {
-            logError("Column of the overflow duration limit and/or vegetation zone class could not be identified");
-            this.headerParsingState = ParsingState.STOP;
-            return true;
+        this.previousClassNo = 0;
+        this.previousDaysLimit = 0;
+        return true;
+    }
+
+    @Override
+    protected boolean checkMetaData() {
+        if (super.checkMetaData() == false)
+            return false;
+        for (final ColTitlePattern value : ColTitlePattern.values()) {
+            if (this.cols.get(value) < 0) {
+                logError("No valid header line with the column titles found");
+                this.headerParsingState = ParsingState.STOP;
+                return false;
+            }
         }
-        this.previousClassNo = 0;
-        this.previousDaysLimit = -1;
         return true;
     }
 
@@ -170,7 +197,7 @@
             classNo = Integer.parseInt(values[this.cols.get(ColTitlePattern.CLASSNO)]);
         }
         catch (final Exception e) {
-            logError("Overflow days limit and/or vegetation zone class could not be parsed: line " + this.in.getLineNumber());
+            logLineWarning("Invalid overflow days limit and/or vegetation zone class (%s)", e.getMessage());
             return null;
         }
         // Check completeness of vegetation zone type set, if needed
@@ -182,12 +209,46 @@
         // logError("Unknown vegetation zone class: line " + this.in.getLineNumber());
         // return null;
         // }
+        boolean classokay = false;
+        final Session session = ImporterSession.getInstance().getDatabaseSession();
+        for (final VegetationType vt : VegetationType.getTypes(session)) {
+            if (classNo == vt.getId().intValue()) {
+                final String dbname = vt.getLocalizedName(Locale.GERMAN);
+                if (!values[0].equalsIgnoreCase(dbname)) {
+                    logLineWarning("Wrong Vegetationstyp or Vegetationsklasse (%d is '%s' in the database)", classNo, dbname);
+                    return null;
+                }
+                classokay = true;
+                break;
+            }
+        }
+        if (!classokay) {
+            logLineWarning("Unknown Vegetationsklasse");
+            return null;
+        }
+
         this.previousClassNo = classNo;
         final int minDays = this.previousDaysLimit;
         this.previousDaysLimit = daysLimit;
-        final int red = (this.cols.get(ColTitlePattern.COLOR_R) >= 0) ? Integer.parseInt(values[this.cols.get(ColTitlePattern.COLOR_R)]) : 0;
-        final int green = (this.cols.get(ColTitlePattern.COLOR_G) >= 0) ? Integer.parseInt(values[this.cols.get(ColTitlePattern.COLOR_G)]) : 0;
-        final int blue = (this.cols.get(ColTitlePattern.COLOR_B) >= 0) ? Integer.parseInt(values[this.cols.get(ColTitlePattern.COLOR_B)]) : 0;
-        return new VegetationZoneImport(classNo, minDays, daysLimit, red, green, blue);
+        final Integer red = parseIntegerCheckNull(values, this.cols.get(ColTitlePattern.COLOR_R));
+        final Integer green = parseIntegerCheckNull(values, this.cols.get(ColTitlePattern.COLOR_G));
+        final Integer blue = parseIntegerCheckNull(values, this.cols.get(ColTitlePattern.COLOR_B));
+        if ((red == null) || (green == null) || (blue == null)) {
+            logLineWarning("One or more color components invalid or missing");
+            return null;
+        }
+        if ((red.intValue() < 0) || (red.intValue() > 255)) {
+            logLineWarning("Invalid red value");
+            return null;
+        }
+        if ((green.intValue() < 0) || (green.intValue() > 255)) {
+            logLineError("Invalid green value");
+            return null;
+        }
+        if ((blue.intValue() < 0) || (blue.intValue() > 255)) {
+            logLineError("Invalid blue value");
+            return null;
+        }
+        return new VegetationZoneImport(classNo, minDays, daysLimit, red.intValue(), green.intValue(), blue.intValue());
     }
 }

http://dive4elements.wald.intevation.org