teichmann@5829: package org.dive4elements.river.importer.parsers; sascha@1211: sascha@1211: import java.io.BufferedReader; sascha@1211: import java.io.File; sascha@1211: import java.io.FileInputStream; sascha@1211: import java.io.InputStreamReader; sascha@1211: import java.io.IOException; sascha@1211: import java.math.BigDecimal; sascha@1211: sascha@1211: import org.apache.log4j.Logger; sascha@1211: teichmann@5829: import org.dive4elements.river.importer.ImportDischargeTable; teichmann@5829: import org.dive4elements.river.importer.ImportDischargeTableValue; sascha@1211: sascha@1211: import java.util.regex.Pattern; sascha@1211: import java.util.regex.Matcher; sascha@1211: sascha@1211: import java.util.Date; sascha@1211: import java.util.Calendar; sascha@1211: teichmann@5829: import org.dive4elements.river.importer.ImportTimeInterval; sascha@1211: felix@5330: /** Parse *.at (Abflusstafeln?) files. */ sascha@1211: public class AtFileParser { sascha@1211: sascha@1211: public static final String ENCODING = "ISO-8859-1"; sascha@1211: sascha@1211: private static Logger logger = Logger.getLogger(AtFileParser.class); sascha@1211: sascha@1211: // regular expression from hell to find out time range sascha@1211: public static final Pattern DATE_LINE = Pattern.compile( sascha@1211: "^\\*\\s*Abflu[^t]+tafel?\\s*([^\\d]+)" + sascha@1211: "(\\d{1,2})?\\.?(\\d{1,2})?\\.?(\\d{2,4})\\s*(?:(?:bis)|-)?\\s*" + sascha@1211: "(?:(\\d{1,2})?\\.?(\\d{1,2})?\\.?(\\d{2,4}))?\\s*.*$"); sascha@1211: sascha@1211: public AtFileParser() { sascha@1211: } sascha@1211: sascha@1211: sascha@1211: public ImportDischargeTable parse(File file) throws IOException { sascha@1211: return parse(file, "", 0); sascha@1211: } sascha@1211: sascha@1211: public ImportDischargeTable parse( sascha@1211: File file, sascha@1211: String prefix, sascha@1211: int kind sascha@1211: ) sascha@1211: throws IOException { sascha@1211: sascha@1211: logger.info("parsing AT file: " + file); sascha@1211: sascha@1211: BufferedReader br = null; sascha@1211: sascha@1211: String line = null; sascha@1211: sascha@1211: boolean beginning = true; sascha@1211: sascha@1211: ImportDischargeTable dischargeTable = sascha@1211: new ImportDischargeTable(kind, prefix + file.getName()); sascha@1211: sascha@1211: Date from = null; sascha@1211: Date to = null; sascha@1211: sascha@1211: try { sascha@1211: br = new BufferedReader( sascha@1211: new InputStreamReader( sascha@1211: new FileInputStream(file), ENCODING)); sascha@1211: sascha@1211: while ((line = br.readLine()) != null) { sascha@1211: sascha@1211: String tmp = line.trim(); sascha@1211: sascha@1211: if (tmp.length() == 0) { sascha@1211: continue; sascha@1211: } sascha@1211: sascha@1211: Matcher m = DATE_LINE.matcher(tmp); sascha@1211: if (m.matches()) { sascha@1211: from = guessDate(m.group(2), m.group(3), m.group(4)); sascha@1211: to = guessDate(m.group(5), m.group(6), m.group(7)); sascha@1211: if (from == null) { sascha@1211: Date t = from; from = to; to = t; sascha@1211: } sascha@1211: continue; sascha@1211: } sascha@1211: sascha@1211: if (tmp.startsWith("#! name=")) { sascha@1211: // XXX Skip the name, because we don't know where to save sascha@1211: // it at the moment sascha@1211: sascha@1211: //String name = tmp.substring(8); sascha@1211: continue; sascha@1211: } sascha@1211: sascha@1211: if (tmp.startsWith("#") || tmp.startsWith("*")) { sascha@1211: continue; sascha@1211: } sascha@1211: sascha@1211: String[] splits = tmp.replace(',', '.').split("\\s+"); sascha@1211: sascha@1211: if ((splits.length < 2) || (splits.length > 11)) { sascha@1211: logger.warn("Found an invalid row in the AT file."); sascha@1211: continue; sascha@1211: } sascha@1211: sascha@1211: String strW = splits[0].trim(); sascha@1211: double W = Double.parseDouble(strW); sascha@1211: sascha@1211: /* shift is used to differenciate between lines with sascha@1211: * exactly 10 Qs and lines with less than 10 Qs. The shift sascha@1211: * is only modified when it is the first line. sascha@1211: */ sascha@1211: int shift = -1; sascha@1211: sascha@1211: if (splits.length != 11 && beginning) { sascha@1211: shift = 10 - splits.length; sascha@1211: } sascha@1211: sascha@1211: sascha@1211: for (int i = 1; i < splits.length; i++) { sascha@1211: double iW = W + shift + i; sascha@1211: double iQ = Double.parseDouble(splits[i].trim()); sascha@1211: sascha@1211: dischargeTable.addDischargeTableValue( sascha@1211: new ImportDischargeTableValue( sascha@1211: new BigDecimal(iQ/100.0), sascha@1211: new BigDecimal(iW/100.0))); sascha@1211: } sascha@1211: sascha@1211: beginning = false; sascha@1211: } sascha@1211: } sascha@1211: catch (NumberFormatException pe) { sascha@3660: logger.warn("AT: invalid number " + pe.getMessage()); sascha@1211: } sascha@1211: finally { sascha@1211: if (br != null) { sascha@1211: br.close(); sascha@1211: } sascha@1211: } sascha@1211: sascha@1211: if (from != null) { sascha@1211: if (to != null && from.compareTo(to) > 0) { sascha@1211: Date t = from; from = to; to = t; sascha@1211: } sascha@1211: logger.info("from: " + from + " to: " + to); sascha@1211: ImportTimeInterval interval = new ImportTimeInterval(from, to); sascha@1211: dischargeTable.setTimeInterval(interval); sascha@1211: } sascha@1211: sascha@1211: logger.info("Finished parsing AT file: " + file); sascha@1211: sascha@1211: return dischargeTable; sascha@1211: } sascha@1211: sascha@1211: public static Date guessDate(String day, String month, String year) { felix@5330: // TODO evaluate whether DateGuesser class can do that. sascha@1211: if (day == null && month == null && year == null) { sascha@1211: return null; sascha@1211: } sascha@1211: sascha@1211: logger.debug("day: " + day + " month: " + month + " year: " + year); sascha@1211: sascha@1211: int dayI = 15; sascha@1211: if (day != null) { sascha@1211: try { sascha@1211: dayI = Integer.parseInt(day.trim()); sascha@1211: } sascha@1211: catch (NumberFormatException nfe) { sascha@1211: } sascha@1211: } sascha@1211: sascha@1211: int monthI = 6; sascha@1211: if (month != null) { sascha@1211: try { sascha@1211: monthI = Integer.parseInt(month.trim()); sascha@1211: } sascha@1211: catch (NumberFormatException nfe) { sascha@1211: } sascha@1211: } sascha@1211: sascha@1211: int yearI = 1900; sascha@1211: if (year != null) { sascha@1211: try { sascha@1211: yearI = Integer.parseInt(year.trim()); sascha@1211: if (yearI < 100) { sascha@1211: if (yearI < 20) { sascha@1211: yearI += 2000; sascha@1211: } sascha@1211: else { sascha@1211: yearI += 1900; sascha@1211: } sascha@1211: } sascha@1211: } sascha@1211: catch (NumberFormatException nfe) { sascha@1211: } sascha@1211: } sascha@1211: sascha@1211: Calendar cal = Calendar.getInstance(); sascha@1211: cal.set(yearI, monthI-1, dayI, 12, 0, 0); sascha@1211: long ms = cal.getTimeInMillis(); sascha@1211: cal.setTimeInMillis(ms - ms%1000); sascha@1211: return cal.getTime(); sascha@1211: } felix@5331: felix@5331: felix@5331: /** Parse one or more files, (useful for debugging), */ felix@5331: public static void main(String [] args) { felix@5331: felix@5331: AtFileParser parser = new AtFileParser(); felix@5331: felix@5331: try { felix@5331: for (String arg: args) { felix@5331: parser.parse(new File(arg)); felix@5331: } felix@5331: } catch(Exception e) { felix@5331: logger.error("Exception caught " + e); felix@5331: } felix@5331: } sascha@1211: } sascha@1211: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :