teichmann@5844: /* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde teichmann@5844: * Software engineering by Intevation GmbH teichmann@5844: * teichmann@5992: * This file is Free Software under the GNU AGPL (>=v3) teichmann@5844: * and comes with ABSOLUTELY NO WARRANTY! Check out the teichmann@5992: * documentation coming with Dive4Elements River for details. teichmann@5844: */ teichmann@5844: teichmann@5829: package org.dive4elements.river.importer.parsers; ingo@3328: ingo@3329: import java.io.File; ingo@3329: import java.io.IOException; ingo@3328: import java.text.NumberFormat; ingo@3328: import java.text.ParseException; ingo@3328: import java.util.ArrayList; ingo@3328: import java.util.List; ingo@3328: import java.util.regex.Matcher; ingo@3328: import java.util.regex.Pattern; ingo@3328: ingo@3328: import org.apache.log4j.Logger; ingo@3328: tom@8412: import org.dive4elements.river.model.River; tom@8412: import org.dive4elements.river.model.MeasurementStation; tom@8412: tom@8412: import org.dive4elements.river.importer.ImporterSession; teichmann@5829: import org.dive4elements.river.importer.ImportSQRelation; teichmann@5829: import org.dive4elements.river.importer.ImportSQRelationValue; teichmann@5829: import org.dive4elements.river.importer.ImportTimeInterval; teichmann@8187: import org.dive4elements.river.backend.utils.DateUtil; ingo@3328: ingo@3328: ingo@3328: public class SQRelationParser extends LineParser { ingo@3328: ingo@3328: private static final Logger log = ingo@3328: Logger.getLogger(SQRelationParser.class); ingo@3328: ingo@3328: private static final Pattern TIMERANGE_REGEX = ingo@3328: Pattern.compile(".*Zeitraum.*\\s(\\w*)-(\\w*).*"); ingo@3328: ingo@3328: private static final NumberFormat nf = ingo@3328: NumberFormat.getInstance(DEFAULT_LOCALE); ingo@3328: ingo@3328: private List relations; ingo@3328: ingo@3328: private ImportSQRelation current; ingo@3328: ingo@3329: private String currentDescription; ingo@3329: tom@8412: protected River river; ingo@3328: tom@8412: public SQRelationParser(River river) { ingo@3328: relations = new ArrayList(); tom@8412: this.river = river; ingo@3328: } ingo@3328: ingo@3328: ingo@3328: public List getSQRelations() { ingo@3328: return relations; ingo@3328: } ingo@3328: ingo@3328: @Override ingo@3329: public void parse(File file) throws IOException { ingo@3329: this.currentDescription = file.getName(); ingo@3329: super.parse(file); ingo@3329: } ingo@3329: ingo@3329: ingo@3329: @Override ingo@3328: protected void reset() { ingo@3328: current = new ImportSQRelation(); ingo@3328: } ingo@3328: ingo@3328: ingo@3328: @Override ingo@3328: protected void finish() { ingo@3329: if (current != null) { ingo@3329: current.setDescription(currentDescription); ingo@3329: relations.add(current); ingo@3329: } ingo@3328: } ingo@3328: ingo@3328: ingo@3328: @Override ingo@4193: protected void handleLine(int lineNum, String line) { ingo@3328: if (line.startsWith(START_META_CHAR)) { ingo@3328: handleMetaLine(stripMetaLine(line)); ingo@3328: } ingo@3328: else { ingo@3328: handleDataLine(line); ingo@3328: } ingo@3328: } ingo@3328: ingo@3328: ingo@3328: protected void handleMetaLine(String line) { ingo@3328: Matcher m = TIMERANGE_REGEX.matcher(line); ingo@3328: ingo@3328: if (m.matches()) { ingo@3328: String lo = m.group(1); ingo@3328: String hi = m.group(2); ingo@3328: ingo@3328: log.debug("Found timerange " + lo + " - " + hi); ingo@3328: ingo@3328: try { ingo@3328: int low = nf.parse(lo).intValue(); ingo@3328: int high = nf.parse(hi).intValue(); ingo@3328: ingo@3328: current.setTimeInterval(new ImportTimeInterval( tom@7927: DateUtil.getStartDateFromYear(low), tom@7927: DateUtil.getEndDateFromYear(high) ingo@3328: )); ingo@3328: } ingo@3328: catch (ParseException nfe) { ingo@3328: log.warn("Cannot parse time range.", nfe); ingo@3328: } ingo@3328: } ingo@3328: } ingo@3328: ingo@3328: ingo@3328: protected void handleDataLine(String line) { ingo@3328: String[] cols = line.split(SEPERATOR_CHAR); ingo@3328: tom@8690: String parameter = cols[1].trim(); tom@8690: Double km = parseDouble(cols, 3); tom@8690: Double a = parseDouble(cols, 6); tom@8690: Double b = parseDouble(cols, 7); tom@8690: Double qMax = parseDouble(cols, 8); tom@8690: Double rSq = parseDouble(cols, 9); tom@8690: Integer nTot = parseInteger(cols, 10); tom@8690: Integer nOutlier = parseInteger(cols, 11); tom@8690: Double cFer = parseDouble(cols, 12); tom@8690: Double cDuan = parseDouble(cols, 13); teichmann@7252: teichmann@7252: if (km == null || a == null || b == null tom@8690: || qMax == null || parameter.length() == 0 teichmann@7252: ) { teichmann@7252: if (km == null) { tom@8856: log.error( tom@8856: "No km for measurement station: " tom@8856: + "Can not reference measurement station: " teichmann@7252: + line); teichmann@7252: } teichmann@7252: if (a == null || b == null tom@8690: || qMax == null || parameter.length() == 0 teichmann@7252: ) { tom@8856: log.error( tom@8856: "Incomplete SQ-relation row " tom@8856: + "(missing a, b, Qmax or parameter): " teichmann@7252: + line); teichmann@7252: } teichmann@7252: return; rrenkert@5429: } tom@8412: tom@8692: MeasurementStation mStation = ImporterSession.getInstance() tom@8692: .getMeasurementStation( tom@8692: river, tom@8692: km, tom@8692: parameter.equals("A") || parameter.equals("B") tom@8692: ? MeasurementStation.MEASUREMENT_TYPE_SUSP tom@8692: : MeasurementStation.MEASUREMENT_TYPE_BEDLOAD); tom@8412: tom@8692: if (mStation == null) { tom@8692: log.warn("No measurement station fitting parameter " + tom@8692: parameter + " at km " + km + ". Line ignored."); tom@8692: return; tom@8412: } tom@8692: tom@8692: current.addValue(new ImportSQRelationValue( tom@8692: parameter, tom@8692: mStation, tom@8692: a, tom@8692: b, tom@8692: qMax, tom@8692: rSq, tom@8692: nTot, tom@8692: nOutlier, tom@8692: cFer, tom@8692: cDuan tom@8692: )); rrenkert@5429: } rrenkert@5429: tom@8690: private Double parseDouble(String[] values, int idx) { tom@8690: if (idx >= 0 && idx < values.length && !values[idx].isEmpty()) { tom@8690: try { tom@8690: return nf.parse(values[idx]).doubleValue(); tom@8690: } tom@8690: catch (ParseException e) { tom@8690: log.warn("Unparseable value '" + values[idx] + "'"); tom@8690: } ingo@3328: } tom@8690: return null; rrenkert@5429: } rrenkert@5429: tom@8690: private Integer parseInteger(String[] values, int idx) { tom@8690: if (idx >= 0 && idx < values.length && !values[idx].isEmpty()) { tom@8690: try { tom@8690: return nf.parse(values[idx]).intValue(); tom@8690: } tom@8690: catch (ParseException e) { tom@8690: log.warn("Unparseable value '" + values[idx] + "'"); tom@8690: } rrenkert@5429: } tom@8690: return null; ingo@3328: } ingo@3328: } ingo@3328: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :