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@9010: import java.text.DateFormat; mschaefer@9010: import java.text.SimpleDateFormat; mschaefer@8971: import java.util.ArrayList; mschaefer@9010: import java.util.Date; 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.TkhColumnSeriesImport; mschaefer@8971: import org.dive4elements.river.importer.sinfo.importitem.TkhKmLineImport; mschaefer@8971: import org.dive4elements.river.importer.sinfo.importitem.TkhSeriesImport; mschaefer@8971: import org.dive4elements.river.model.sinfo.TkhColumn; mschaefer@8971: import org.dive4elements.river.model.sinfo.TkhValue; mschaefer@8971: mschaefer@8971: /** mschaefer@8971: * Reads and parses the header of a TKH 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 TkhParser extends AbstractParser { mschaefer@8971: mschaefer@8971: /***** FIELDS *****/ mschaefer@8971: mschaefer@8971: private static final Logger log = Logger.getLogger(TkhParser.class); mschaefer@8971: mschaefer@9010: private static final Pattern META_DATUM = Pattern.compile("^#\\sDatum:\\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_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("Transportk((.)|(oe))rperh((.)|(oe))he\\s*\\((.+?)\\)\\s*\\[cm\\].*", Pattern.CASE_INSENSITIVE); mschaefer@8971: mschaefer@9010: private static final DateFormat dateFormat = new SimpleDateFormat("dd.MM.yyyy"); mschaefer@9010: mschaefer@8971: private final TkhSeriesImport tkhGroup; mschaefer@8971: mschaefer@8971: private final List colParsers; mschaefer@8971: mschaefer@8971: mschaefer@8971: /***** CONSTRUCTORS *****/ mschaefer@8971: mschaefer@8971: public TkhParser(final File importPath, final File rootRelativePath, final ImportRiver river) { mschaefer@8971: super(importPath, rootRelativePath, river); mschaefer@8971: this.tkhGroup = new TkhSeriesImport(importPath.getName().replaceAll("\\.csv", "")); mschaefer@8971: this.seriesHeader = new TkhColumnSeriesImport(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.skipSInfoTkh(); 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 TkhParser(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 TkhColumnParser colParser : this.colParsers) mschaefer@8971: colParser.parse(); mschaefer@8971: } mschaefer@8971: mschaefer@8971: @Override mschaefer@8971: protected boolean handleMetaOther() { mschaefer@9010: if (handleMetaDay()) 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@9010: private boolean handleMetaDay() { mschaefer@9010: final Matcher m = META_DATUM.matcher(this.currentLine); mschaefer@8971: if (m.matches()) { mschaefer@9010: Date day = null; mschaefer@9010: try { mschaefer@9010: if (!m.group(1).isEmpty()) mschaefer@9010: day = dateFormat.parse(m.group(1)); mschaefer@9010: } mschaefer@9010: catch (final Exception e) { mschaefer@9010: logError("Invalid date in line " + this.in.getLineNumber()); mschaefer@9010: } mschaefer@9010: this.metaPatternsMatched.add(META_DATUM); mschaefer@9010: this.tkhGroup.setDay(day); mschaefer@9010: if (day == null) mschaefer@9010: logWarning("No date specified"); 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@8971: this.tkhGroup.setComment(this.seriesHeader.getComment()); 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 TkhColumnParser(this.importPath, this.rootRelativePath, this.river, this.tkhGroup, i, m.group(7).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 TkhColumnParser 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 TkhColumnSeriesImport createSeriesImport(final String filename) { mschaefer@8971: throw new UnsupportedOperationException(); mschaefer@8971: } mschaefer@8971: mschaefer@8971: @Override mschaefer@8971: protected TkhKmLineImport createKmLineImport(final Double km, final String[] values) { mschaefer@8971: throw new UnsupportedOperationException(); mschaefer@8971: } mschaefer@8971: }