mschaefer@8971: /* Copyright (C) 2017 by Bundesanstalt für Gewässerkunde mschaefer@8971: * Software engineering by mschaefer@8971: * Björnsen Beratende Ingenieure GmbH mschaefer@8971: * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt mschaefer@8971: * mschaefer@8971: * This file is Free Software under the GNU AGPL (>=v3) mschaefer@8971: * and comes with ABSOLUTELY NO WARRANTY! Check out the mschaefer@8971: * documentation coming with Dive4Elements River for details. mschaefer@8971: */ mschaefer@8971: mschaefer@8971: package org.dive4elements.river.importer.sinfo.parsers; mschaefer@8971: mschaefer@8971: import java.io.File; mschaefer@8971: import java.util.ArrayList; mschaefer@8971: import java.util.HashMap; mschaefer@8971: import java.util.List; mschaefer@8971: import java.util.regex.Matcher; mschaefer@8971: import java.util.regex.Pattern; mschaefer@8971: mschaefer@8971: import org.apache.log4j.Logger; mschaefer@8971: import org.dive4elements.river.importer.Config; mschaefer@8971: import org.dive4elements.river.importer.ImportAnnotationType; mschaefer@8971: import org.dive4elements.river.importer.ImportAttribute; mschaefer@8971: import org.dive4elements.river.importer.ImportRiver; mschaefer@8971: import org.dive4elements.river.importer.common.AbstractParser; mschaefer@8971: import org.dive4elements.river.importer.common.ParsingState; mschaefer@8971: import org.dive4elements.river.importer.sinfo.importitem.InfrastructureKmLineImport; mschaefer@8971: import org.dive4elements.river.importer.sinfo.importitem.InfrastructureSeriesImport; mschaefer@8971: import org.dive4elements.river.model.sinfo.Infrastructure; mschaefer@8971: import org.dive4elements.river.model.sinfo.InfrastructureValue; mschaefer@8971: mschaefer@8971: /** mschaefer@8971: * Reads and parses an infrastructure file mschaefer@8971: * mschaefer@8971: * @author Matthias Schäfer mschaefer@8971: * mschaefer@8971: */ mschaefer@8971: public class InfrastructureParser extends AbstractParser { mschaefer@8971: mschaefer@8971: /***** FIELDS *****/ mschaefer@8971: mschaefer@8971: private static final Logger log = Logger.getLogger(InfrastructureParser.class); mschaefer@8971: mschaefer@8971: private static final Pattern META_TYPE = Pattern.compile("^#\\sInfrastruktur:\\s*([^;]*).*", Pattern.CASE_INSENSITIVE); mschaefer@8971: mschaefer@8971: private static final Pattern META_PROVIDER = Pattern.compile("^#\\sDatenherkunft:\\s*([^;]*).*", Pattern.CASE_INSENSITIVE); mschaefer@8971: mschaefer@8971: private static final Pattern META_EVALUATOR = Pattern.compile("^#\\sAuswerter:\\s*([^;]*).*", Pattern.CASE_INSENSITIVE); mschaefer@8971: mschaefer@8971: private static final Pattern META_YEAR = Pattern.compile("^#\\sStand:\\s*([12]\\d\\d\\d).*", Pattern.CASE_INSENSITIVE); mschaefer@8971: mschaefer@8971: private static final Pattern HEIGHT_COLUMNTITLE = Pattern.compile("((H.he)|(Hoehe))\\s*\\[(.*)\\].*", Pattern.CASE_INSENSITIVE); mschaefer@8971: mschaefer@8971: private static final Pattern BANK_COLUMNTITLE = Pattern.compile("Uferseite.*", Pattern.CASE_INSENSITIVE); mschaefer@8971: mschaefer@8971: private static final String DB_BANK_LEFT = "links"; // TODO: improve database design to make this secure mschaefer@8971: mschaefer@8971: private static final String DB_BANK_RIGHT = "rechts"; mschaefer@8971: mschaefer@8971: private static final String DB_BANK_NULL = ""; mschaefer@8971: mschaefer@8971: private int heightColIndex; mschaefer@8971: mschaefer@8971: private int bankColIndex; mschaefer@8971: mschaefer@8971: private final HashMap bankAttributes; mschaefer@8971: mschaefer@8971: mschaefer@8971: /***** CONSTRUCTORS *****/ mschaefer@8971: mschaefer@8971: public InfrastructureParser(final File importPath, final File rootRelativePath, final ImportRiver river) { mschaefer@8971: super(importPath, rootRelativePath, river); mschaefer@8971: this.heightColIndex = -1; mschaefer@8971: this.bankColIndex = -1; mschaefer@8971: this.bankAttributes = new HashMap<>(); mschaefer@8971: this.bankAttributes.put("links", new ImportAttribute(DB_BANK_LEFT)); mschaefer@8971: this.bankAttributes.put("rechts", new ImportAttribute(DB_BANK_RIGHT)); mschaefer@8971: this.bankAttributes.put("", new ImportAttribute(DB_BANK_NULL)); mschaefer@8971: } mschaefer@8971: mschaefer@8971: mschaefer@8971: /***** METHODS *****/ mschaefer@8971: mschaefer@8971: @Override mschaefer@8971: protected Logger getLog() { mschaefer@8971: return log; mschaefer@8971: } mschaefer@8971: mschaefer@8971: /** mschaefer@8971: * Whether this import type shall be skipped mschaefer@8971: */ mschaefer@8971: public static boolean shallSkip() { mschaefer@8971: return Config.INSTANCE.skipSInfoInfrastructure(); mschaefer@8971: } mschaefer@8971: mschaefer@8971: /** mschaefer@8971: * Creates a list of parsers for all infrastructure import files in a directory mschaefer@8971: */ mschaefer@8971: public static List createParsers(final File importDir, final File relativeDir, final ImportRiver river) { mschaefer@8971: final List parsers = new ArrayList<>(); mschaefer@8988: if (importDir.exists()) mschaefer@8988: for (final File file : listFiles(importDir, ".csv")) mschaefer@8988: parsers.add(new InfrastructureParser(file, new File(relativeDir, file.getName()), river)); mschaefer@8971: return parsers; mschaefer@8971: } mschaefer@8971: mschaefer@8971: @Override mschaefer@8971: protected InfrastructureSeriesImport createSeriesImport(final String filename) { mschaefer@8971: return new InfrastructureSeriesImport(filename); mschaefer@8971: } mschaefer@8971: mschaefer@8971: @Override mschaefer@9011: protected KmMode kmMode() { mschaefer@9011: return KmMode.NONE; mschaefer@8971: } mschaefer@8971: mschaefer@8971: @Override mschaefer@8971: protected boolean handleMetaOther() { mschaefer@8971: if (handleMetaType()) mschaefer@8971: return true; mschaefer@8971: else if (handleMetaProvider()) mschaefer@8971: return true; mschaefer@8971: else if (handleMetaEvaluator()) mschaefer@8971: return true; mschaefer@8971: else if (handleMetaYear()) mschaefer@8971: return true; mschaefer@8971: else mschaefer@8971: return false; mschaefer@8971: } mschaefer@8971: mschaefer@8971: private boolean handleMetaType() { mschaefer@8971: final Matcher m = META_TYPE.matcher(this.currentLine); mschaefer@8971: if (m.matches()) { mschaefer@8971: this.metaPatternsMatched.add(META_TYPE); mschaefer@8988: if (this.river.getAnnotationClassifier() != null) { mschaefer@8988: final ImportAnnotationType type = this.river.getAnnotationClassifier().classifyDescription(m.group(1).trim(), mschaefer@8988: this.river.getAnnotationClassifier().getDefaultType()); mschaefer@8988: this.seriesHeader.setType(type); mschaefer@8988: log.info(String.format("Type name in file: '%s', will be assigned to database name '%s'", m.group(1).trim(), type.getName())); mschaefer@8988: } mschaefer@8971: else { mschaefer@8988: log.error("No annotation types file configured, cannot process type '" + m.group(1).trim() + "'"); mschaefer@8988: this.headerParsingState = ParsingState.STOP; mschaefer@8971: } mschaefer@8971: return true; mschaefer@8971: } mschaefer@8971: return false; mschaefer@8971: } mschaefer@8971: mschaefer@8971: private boolean handleMetaProvider() { mschaefer@8971: final Matcher m = META_PROVIDER.matcher(this.currentLine); mschaefer@8971: if (m.matches()) { mschaefer@8971: this.metaPatternsMatched.add(META_PROVIDER); mschaefer@8971: this.seriesHeader.setProvider(parseMetaInfo(m.group(1).trim())); mschaefer@8971: return true; mschaefer@8971: } mschaefer@8971: return false; mschaefer@8971: } mschaefer@8971: mschaefer@8971: private boolean handleMetaEvaluator() { mschaefer@8971: final Matcher m = META_EVALUATOR.matcher(this.currentLine); mschaefer@8971: if (m.matches()) { mschaefer@8971: this.metaPatternsMatched.add(META_EVALUATOR); mschaefer@8971: this.seriesHeader.setEvaluation_by(parseMetaInfo(m.group(1).trim())); mschaefer@8971: return true; mschaefer@8971: } mschaefer@8971: return false; mschaefer@8971: } mschaefer@8971: mschaefer@8971: private boolean handleMetaYear() { mschaefer@8971: final Matcher m = META_YEAR.matcher(this.currentLine); mschaefer@8971: if (m.matches()) { mschaefer@8971: this.metaPatternsMatched.add(META_YEAR); mschaefer@8971: this.seriesHeader.setYear(Integer.parseInt(m.group(1))); mschaefer@8971: return true; mschaefer@8971: } mschaefer@8971: return false; mschaefer@8971: } mschaefer@8971: mschaefer@8971: @Override mschaefer@8971: protected boolean handleMetaColumnTitles() { mschaefer@8971: if (super.handleMetaColumnTitles()) { mschaefer@8971: for (int i = 1; i <= this.columnTitles.size() - 1; i++) { mschaefer@8971: if (HEIGHT_COLUMNTITLE.matcher(this.columnTitles.get(i)).matches()) mschaefer@8971: this.heightColIndex = i; mschaefer@8971: else if (BANK_COLUMNTITLE.matcher(this.columnTitles.get(i)).matches()) mschaefer@8971: this.bankColIndex = i; mschaefer@8971: } mschaefer@8971: if (this.bankColIndex < 0) mschaefer@8971: logWarning("Column of river side value could not be identified, missing column title 'Uferseite'"); mschaefer@8971: if (this.heightColIndex < 0) { mschaefer@8971: logError("Column of height values could not be identified, missing column title 'Höhe...'"); mschaefer@8971: this.headerParsingState = ParsingState.STOP; mschaefer@8971: return false; mschaefer@8971: } mschaefer@8971: return true; mschaefer@8971: } mschaefer@8971: else mschaefer@8971: return false; mschaefer@8971: } mschaefer@8971: mschaefer@8971: @Override mschaefer@8971: protected InfrastructureKmLineImport createKmLineImport(final Double km, final String[] values) { mschaefer@8971: if (parseDoubleWithNull(values[this.heightColIndex]) == null) { mschaefer@8971: logError("Invalid height value in line " + this.in.getLineNumber()); mschaefer@8971: return null; mschaefer@8971: } mschaefer@8971: if ((this.bankColIndex >= 0) && this.bankAttributes.containsKey(values[this.bankColIndex].trim().toLowerCase())) mschaefer@8971: return new InfrastructureKmLineImport(km, parseDoubleWithNull(values[this.heightColIndex]).doubleValue(), mschaefer@8971: this.bankAttributes.get(values[this.bankColIndex].trim().toLowerCase())); mschaefer@8971: else { mschaefer@8971: logError("Invalid bank value in line " + this.in.getLineNumber()); mschaefer@8971: return null; mschaefer@8971: } mschaefer@8971: } mschaefer@8971: }