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.io.FileInputStream; mschaefer@8971: import java.io.IOException; mschaefer@8971: import java.io.InputStreamReader; mschaefer@8971: import java.io.LineNumberReader; mschaefer@8971: import java.util.ArrayList; 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.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.FlowDepthColumnSeriesImport; mschaefer@8971: import org.dive4elements.river.importer.sinfo.importitem.FlowDepthKmLineImport; mschaefer@8971: import org.dive4elements.river.importer.sinfo.importitem.FlowDepthSeriesImport; mschaefer@8971: import org.dive4elements.river.model.sinfo.FlowDepthColumn; mschaefer@8971: import org.dive4elements.river.model.sinfo.FlowDepthValue; mschaefer@8971: mschaefer@8971: /** mschaefer@8971: * Reads and parses the header of a flow depth file and handles the parse and store of the columns mschaefer@8971: * mschaefer@8971: * @author Matthias Schäfer mschaefer@8971: * mschaefer@8971: */ mschaefer@8971: public class FlowDepthParser extends AbstractParser { mschaefer@8971: mschaefer@8971: /***** FIELDS *****/ mschaefer@8971: mschaefer@8971: private static final Logger log = Logger.getLogger(FlowDepthParser.class); mschaefer@8971: mschaefer@8971: private static final Pattern META_YEAR = Pattern.compile("^#\\sBezugsjahr:\\s*([12]\\d\\d\\d).*", 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_SOUNDING = Pattern.compile("^#\\sPeilung:\\s*([^;]*).*", Pattern.CASE_INSENSITIVE); mschaefer@8971: mschaefer@8971: private static final Pattern META_TYPE = Pattern.compile("^#\\sTyp:\\s*([^;]*).*", Pattern.CASE_INSENSITIVE); mschaefer@8971: mschaefer@8971: private static final Pattern COLUMN_TITLE = Pattern.compile("Flie((.)|(ss))tiefe\\s*\\((.+?)\\)\\s*\\[m\\].*", Pattern.CASE_INSENSITIVE); mschaefer@8971: mschaefer@8971: private final FlowDepthSeriesImport tkhGroup; mschaefer@8971: mschaefer@8971: private final List colParsers; mschaefer@8971: mschaefer@8971: mschaefer@8971: /***** CONSTRUCTORS *****/ mschaefer@8971: mschaefer@8971: public FlowDepthParser(final File importPath, final File rootRelativePath, final ImportRiver river) { mschaefer@8971: super(importPath, rootRelativePath, river); mschaefer@8971: this.tkhGroup = new FlowDepthSeriesImport(importPath.getName().replaceAll("\\.csv", "")); mschaefer@8971: this.seriesHeader = new FlowDepthColumnSeriesImport(this.tkhGroup.getFilename(), this.tkhGroup, null, null); mschaefer@8971: this.colParsers = new ArrayList<>(); 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.skipSInfoFlowDepth(); mschaefer@8971: } mschaefer@8971: mschaefer@8971: /** mschaefer@8971: * Creates a list of parsers for all collision 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 FlowDepthParser(file, new File(relativeDir, file.getName()), river)); mschaefer@8971: return parsers; mschaefer@8971: } mschaefer@8971: mschaefer@8971: @Override mschaefer@8971: public void parse() throws IOException { mschaefer@8971: getLog().info("Start parsing:;'" + this.rootRelativePath + "'"); mschaefer@8971: // this.seriesHeader = createSeriesImport(this.importPath.getName().replaceAll("\\.csv", "")); mschaefer@8971: this.metaPatternsMatched.clear(); mschaefer@8971: this.kmExists.clear(); mschaefer@8971: this.colParsers.clear(); mschaefer@8971: this.headerParsingState = ParsingState.CONTINUE; mschaefer@8971: try { mschaefer@8971: try { mschaefer@8971: this.in = new LineNumberReader(new InputStreamReader(new FileInputStream(this.importPath), ENCODING)); mschaefer@8971: } mschaefer@8971: catch (final Exception e) { mschaefer@8971: logError("Could not open (" + e.getMessage() + ")"); mschaefer@8971: this.headerParsingState = ParsingState.STOP; mschaefer@8971: } mschaefer@8971: this.currentLine = null; mschaefer@8971: while (this.headerParsingState == ParsingState.CONTINUE) { mschaefer@8971: this.currentLine = this.in.readLine(); mschaefer@8971: if (this.currentLine == null) mschaefer@8971: break; mschaefer@8971: this.currentLine = this.currentLine.trim(); mschaefer@8971: if (this.currentLine.isEmpty()) mschaefer@8971: continue; mschaefer@8971: handleMetaLine(); mschaefer@8971: } mschaefer@8971: } mschaefer@8971: finally { mschaefer@8971: if (this.in != null) { mschaefer@8971: this.in.close(); mschaefer@8971: this.in = null; mschaefer@8971: } mschaefer@8971: } mschaefer@8971: if (this.headerParsingState == ParsingState.STOP) { mschaefer@8971: logError("Parsing of the file stopped due to a severe error"); mschaefer@8971: return; mschaefer@8971: } mschaefer@8971: for (final FlowDepthColumnParser colParser : this.colParsers) mschaefer@8971: colParser.parse(); mschaefer@8971: } mschaefer@8971: mschaefer@8971: @Override mschaefer@8971: protected boolean handleMetaOther() { mschaefer@8971: if (handleMetaYear()) mschaefer@8971: return true; mschaefer@8971: else if (handleMetaType()) mschaefer@8971: return true; mschaefer@8971: else if (handleMetaSounding()) mschaefer@8971: return true; mschaefer@8971: else if (handleMetaEvaluator()) mschaefer@8971: return true; mschaefer@8971: else 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.tkhGroup.setYear(Integer.parseInt(m.group(1))); mschaefer@8971: return true; mschaefer@8971: } 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: return m.matches(); mschaefer@8971: } mschaefer@8971: mschaefer@8971: private boolean handleMetaSounding() { mschaefer@8971: final Matcher m = META_SOUNDING.matcher(this.currentLine); mschaefer@8971: if (m.matches()) { mschaefer@8971: this.metaPatternsMatched.add(META_SOUNDING); mschaefer@8971: this.tkhGroup.setSounding_info(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.tkhGroup.setEvaluation_by(parseMetaInfo(m.group(1).trim())); 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: return false; mschaefer@8971: this.tkhGroup.setKmrange_info(this.seriesHeader.getKmrange_info()); mschaefer@9038: this.tkhGroup.setNotes(this.seriesHeader.getNotes()); mschaefer@8971: for (int i = 1; i <= this.columnTitles.size() - 1; i++) { mschaefer@8971: final Matcher m = COLUMN_TITLE.matcher(this.columnTitles.get(i)); mschaefer@8971: if (m.matches()) mschaefer@8971: this.colParsers.add(new FlowDepthColumnParser(this.importPath, this.rootRelativePath, this.river, this.tkhGroup, i, m.group(4).trim())); mschaefer@8971: else mschaefer@8971: logWarning("No title found in column " + i + ", skipped"); mschaefer@8971: } mschaefer@8971: return true; mschaefer@8971: } mschaefer@8971: mschaefer@8971: @Override mschaefer@8971: public void store() { mschaefer@8971: if (this.headerParsingState != ParsingState.STOP) { mschaefer@8971: this.tkhGroup.getPeer(this.river.getPeer()); mschaefer@8971: for (final FlowDepthColumnParser colParser : this.colParsers) mschaefer@8971: colParser.store(); mschaefer@8971: } mschaefer@8971: else mschaefer@8971: logWarning("Severe parsing errors, not storing series '" + this.tkhGroup.getFilename() + "'"); mschaefer@8971: } mschaefer@8971: mschaefer@8971: @Override mschaefer@8971: protected FlowDepthColumnSeriesImport createSeriesImport(final String filename) { mschaefer@8971: throw new UnsupportedOperationException(); mschaefer@8971: } mschaefer@8971: mschaefer@8971: @Override mschaefer@8971: protected FlowDepthKmLineImport createKmLineImport(final Double km, final String[] values) { mschaefer@8971: throw new UnsupportedOperationException(); mschaefer@8971: } mschaefer@8971: }