ingo@198: package de.intevation.flys.importer; ingo@198: ingo@198: import java.io.BufferedReader; ingo@198: import java.io.File; ingo@198: import java.io.FileInputStream; ingo@198: import java.io.InputStreamReader; ingo@198: import java.io.IOException; ingo@198: import java.math.BigDecimal; ingo@198: import java.text.NumberFormat; ingo@198: import java.text.ParseException; ingo@198: ingo@198: import org.apache.log4j.Logger; ingo@198: ingo@198: import de.intevation.flys.importer.ImportDischargeTable; ingo@198: import de.intevation.flys.importer.ImportDischargeTableValue; ingo@198: sascha@485: import java.util.regex.Pattern; sascha@485: import java.util.regex.Matcher; sascha@485: sascha@485: import java.util.Date; sascha@485: import java.util.Calendar; ingo@198: ingo@198: public class AtFileParser { ingo@198: ingo@198: public static final String ENCODING = "ISO-8859-1"; ingo@198: ingo@198: private static Logger logger = Logger.getLogger(AtFileParser.class); ingo@198: ingo@198: private static NumberFormat nf = NumberFormat.getInstance(); ingo@198: ingo@198: sascha@485: // regular expression from hell to find out time range sascha@485: public static final Pattern DATE_LINE = Pattern.compile( sascha@485: "^\\*\\s*Abflu[^t]+tafel?\\s*([^\\d]+)" + sascha@485: "(\\d{1,2})?\\.?(\\d{1,2})?\\.?(\\d{2,4})\\s*(?:(?:bis)|-)?\\s*" + sascha@485: "(?:(\\d{1,2})?\\.?(\\d{1,2})?\\.?(\\d{2,4}))?\\s*.*$"); sascha@485: ingo@198: public AtFileParser() { ingo@198: } ingo@198: ingo@198: ingo@198: public ImportDischargeTable parse(ImportGauge gauge) throws IOException { ingo@198: ingo@198: File file = gauge.getAtFile(); ingo@198: ingo@198: logger.info("parsing AT file: " + file); ingo@198: ingo@198: BufferedReader br = null; ingo@198: ingo@198: String line = null; ingo@198: ingo@198: boolean beginning = true; ingo@198: ingo@198: ImportDischargeTable dischargeTable = new ImportDischargeTable(); ingo@198: sascha@485: Date from = null; sascha@485: Date to = null; sascha@485: ingo@198: try { ingo@198: br = new BufferedReader( ingo@198: new InputStreamReader( ingo@198: new FileInputStream(file), ENCODING)); ingo@198: ingo@198: while ((line = br.readLine()) != null) { sascha@485: ingo@198: String tmp = line.trim(); ingo@198: ingo@198: if (tmp.length() == 0) { ingo@198: continue; ingo@198: } ingo@198: sascha@485: Matcher m = DATE_LINE.matcher(tmp); sascha@485: if (m.matches()) { sascha@485: from = guessDate(m.group(1), m.group(2), m.group(3)); sascha@485: to = guessDate(m.group(4), m.group(5), m.group(6)); sascha@485: if (from == null) { sascha@485: Date t = from; from = to; to = t; sascha@485: } sascha@485: continue; sascha@485: } sascha@485: ingo@198: if (tmp.startsWith("#! name=")) { ingo@198: // XXX Skip the name, because we don't know where to save ingo@198: // it at the moment ingo@198: ingo@198: //String name = tmp.substring(8); ingo@198: continue; ingo@198: } ingo@198: ingo@198: if (tmp.startsWith("#") || tmp.startsWith("*")) { ingo@198: continue; ingo@198: } ingo@198: ingo@198: String[] splits = tmp.replace(',', '.').split("\\s+"); ingo@198: ingo@198: if ((splits.length < 2) || (splits.length > 11)) { ingo@198: logger.warn("Found an invalid row in the AT file."); ingo@198: continue; ingo@198: } ingo@198: ingo@198: String strW = splits[0].trim(); ingo@198: double W = nf.parse(strW).doubleValue(); ingo@198: ingo@198: /* shift is used to differenciate between lines with ingo@198: * exactly 10 Qs and lines with less than 10 Qs. The shift ingo@198: * is only modified when it is the first line. ingo@198: */ ingo@198: int shift = 0; ingo@198: ingo@198: if (splits.length != 11 && beginning) { ingo@198: shift = 11 - splits.length; ingo@198: } ingo@198: ingo@198: ingo@198: for (int i = 1; i < splits.length; i++) { ingo@198: double iW = W + shift + i; ingo@198: double iQ = nf.parse(splits[i].trim()).doubleValue(); ingo@198: ingo@198: dischargeTable.addDischargeTableValue( ingo@198: new ImportDischargeTableValue( ingo@198: new BigDecimal(iQ/100.0), ingo@198: new BigDecimal(iW/100.0))); ingo@198: } ingo@198: ingo@198: beginning = false; ingo@198: } ingo@198: } ingo@198: catch (ParseException pe) { ingo@198: logger.warn(pe.getMessage()); ingo@198: } ingo@198: finally { ingo@198: if (br != null) { ingo@198: br.close(); ingo@198: } ingo@198: } ingo@198: ingo@198: logger.info("Finished parsing AT file: " + file); ingo@198: ingo@198: return dischargeTable; ingo@198: } sascha@485: sascha@485: public static Date guessDate(String day, String month, String year) { sascha@485: if (day == null && month == null && year == null) { sascha@485: return null; sascha@485: } sascha@485: sascha@485: int dayI = 15; sascha@485: if (day != null) { sascha@485: try { sascha@485: dayI = Integer.parseInt(day.trim()); sascha@485: } sascha@485: catch (NumberFormatException nfe) { sascha@485: } sascha@485: } sascha@485: sascha@485: int monthI = 6; sascha@485: if (month != null) { sascha@485: try { sascha@485: monthI = Integer.parseInt(month.trim()); sascha@485: } sascha@485: catch (NumberFormatException nfe) { sascha@485: } sascha@485: } sascha@485: sascha@485: int yearI = 1900; sascha@485: if (year != null) { sascha@485: try { sascha@485: yearI = Integer.parseInt(year.trim()); sascha@485: if (yearI < 100) { sascha@485: if (yearI < 20) { sascha@485: yearI += 2000; sascha@485: } sascha@485: else { sascha@485: yearI += 1900; sascha@485: } sascha@485: } sascha@485: } sascha@485: catch (NumberFormatException nfe) { sascha@485: } sascha@485: } sascha@485: sascha@485: Calendar cal = Calendar.getInstance(); sascha@485: cal.set(yearI, monthI-1, dayI); sascha@485: return cal.getTime(); sascha@485: } ingo@198: } ingo@198: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :