sascha@1196: package de.intevation.flys.importer; sascha@1196: sascha@1196: import java.util.Map; sascha@1196: import java.util.Stack; sascha@1196: import java.util.TreeMap; sascha@1196: sascha@1196: import java.util.regex.Pattern; sascha@1196: import java.util.regex.Matcher; sascha@1196: sascha@1196: import java.io.File; sascha@1196: import java.io.InputStreamReader; sascha@1196: import java.io.LineNumberReader; sascha@1196: import java.io.FileInputStream; sascha@1196: import java.io.IOException; sascha@1196: sascha@1196: import org.apache.log4j.Logger; sascha@1196: sascha@1196: public class PRFParser sascha@1196: { sascha@1196: private static Logger log = Logger.getLogger(PRFParser.class); sascha@1196: sascha@1196: public static final String ENCODING = sascha@1196: System.getProperty("flys.backend.prf.encoding", "ISO-8859-1"); sascha@1196: sascha@1196: public static final Pattern DATA_PATTERN = sascha@1196: Pattern.compile( sascha@1196: "\\((\\d+)x\\s*,\\s*(\\d+)\\(" + sascha@1196: "\\s*f(\\d+)\\.(\\d+)\\s*,\\s*f(\\d+)\\.(\\d+)\\s*\\)?\\)?"); sascha@1196: sascha@1196: public static final Pattern KM_PATTERN = sascha@1196: Pattern.compile("\\((\\d+)x\\s*,\\s*f(\\d+)\\.(\\d+)\\s*\\)?"); sascha@1196: sascha@1196: public static class DataFormat { sascha@1196: sascha@1196: protected int deleteChars; sascha@1196: protected int maxRepetitions; sascha@1196: protected int firstIntegerPlaces; sascha@1196: protected int firstFractionPlaces; sascha@1196: protected int secondIntegerPlaces; sascha@1196: protected int secondFractionPlaces; sascha@1196: sascha@1196: public DataFormat() { sascha@1196: } sascha@1196: sascha@1196: public DataFormat(Matcher m) { sascha@1196: deleteChars = Integer.parseInt(m.group(1)); sascha@1196: maxRepetitions = Integer.parseInt(m.group(2)); sascha@1196: firstIntegerPlaces = Integer.parseInt(m.group(3)); sascha@1196: firstFractionPlaces = Integer.parseInt(m.group(4)); sascha@1196: secondIntegerPlaces = Integer.parseInt(m.group(5)); sascha@1196: secondFractionPlaces = Integer.parseInt(m.group(6)); sascha@1196: } sascha@1196: sascha@1197: public boolean extractData(String line, Map dest) sascha@1197: throws NumberFormatException sascha@1197: { sascha@1196: //TODO: Implement me! sascha@1197: return true; sascha@1196: } sascha@1196: } // class DataFormat sascha@1196: sascha@1196: public static class KMFormat { sascha@1196: protected int deleteChars; sascha@1196: protected int integerPlaces; sascha@1196: protected int fractionPlaces; sascha@1196: sascha@1197: protected double scale; sascha@1197: protected double shift; sascha@1197: sascha@1196: public KMFormat() { sascha@1196: } sascha@1196: sascha@1196: public KMFormat(Matcher m) { sascha@1196: deleteChars = Integer.parseInt(m.group(1)); sascha@1196: integerPlaces = Integer.parseInt(m.group(2)); sascha@1196: fractionPlaces = Integer.parseInt(m.group(3)); sascha@1197: sascha@1197: shift = Math.pow(10, fractionPlaces); sascha@1197: scale = 1d/shift; sascha@1196: } sascha@1196: sascha@1197: public double extractKm(String line) throws NumberFormatException { sascha@1197: sascha@1197: if (line.length() <= deleteChars) { sascha@1197: throw new NumberFormatException("line too short"); sascha@1197: } sascha@1197: sascha@1197: String kmS = sascha@1197: line.substring(deleteChars, deleteChars+integerPlaces); sascha@1197: sascha@1197: double km = Double.parseDouble(kmS.trim()); sascha@1197: sascha@1197: return fractionPlaces > 0 sascha@1197: ? ((int)((scale*km)*shift))/shift sascha@1197: : km; sascha@1196: } sascha@1196: } // class KMFormat sascha@1196: sascha@1196: protected Map> data; sascha@1196: sascha@1196: public PRFParser() { sascha@1196: data = new TreeMap>(); sascha@1196: } sascha@1196: sascha@1196: sascha@1196: public boolean parse(File file) { sascha@1196: sascha@1196: if (!(file.isFile() && file.canRead())) { sascha@1196: log.warn("cannot open file '" + file + "'"); sascha@1196: return false; sascha@1196: } sascha@1196: sascha@1196: log.info("parsing PRF file: '" + file + "'"); sascha@1196: sascha@1196: LineNumberReader in = null; sascha@1196: sascha@1196: try { sascha@1196: in = sascha@1196: new LineNumberReader( sascha@1196: new InputStreamReader( sascha@1196: new FileInputStream(file), ENCODING)); sascha@1196: sascha@1196: String line = in.readLine(); sascha@1196: sascha@1196: if (line == null || (line = line.trim()).length() == 0) { sascha@1196: log.warn("file is empty."); sascha@1196: return false; sascha@1196: } sascha@1196: sascha@1196: Matcher m = DATA_PATTERN.matcher(line); sascha@1196: sascha@1196: if (!m.matches()) { sascha@1196: log.warn("First line does not look like a PRF data pattern."); sascha@1196: return false; sascha@1196: } sascha@1196: sascha@1196: DataFormat dataFormat = new DataFormat(m); sascha@1196: sascha@1197: if ((line = in.readLine()) == null sascha@1197: || (line = line.trim()).length() == 0) { sascha@1196: log.warn("premature EOF. Expected integer in line 2"); sascha@1196: return false; sascha@1196: } sascha@1196: sascha@1196: try { sascha@1196: if (Integer.parseInt(line) != dataFormat.maxRepetitions) { sascha@1196: log.warn("Expected " + sascha@1196: dataFormat.maxRepetitions + " in line 2"); sascha@1196: return false; sascha@1196: } sascha@1196: } sascha@1196: catch (NumberFormatException nfe) { sascha@1196: log.warn("invalid integer in line 2", nfe); sascha@1196: return false; sascha@1196: } sascha@1196: sascha@1196: if ((line = in.readLine()) == null) { sascha@1196: log.warn( sascha@1196: "premature EOF. Expected pattern for km extraction"); sascha@1196: return false; sascha@1196: } sascha@1196: sascha@1196: m = KM_PATTERN.matcher(line); sascha@1196: sascha@1196: if (!m.matches()) { sascha@1196: log.warn( sascha@1196: "line 4 does not look like a PRF km extraction pattern."); sascha@1196: return false; sascha@1196: } sascha@1196: sascha@1197: KMFormat kmFormat = new KMFormat(m); sascha@1197: sascha@1197: if ((line = in.readLine()) == null sascha@1197: || (line = line.trim()).length() == 0) { sascha@1197: log.warn("premature EOF. Expected skip row count."); sascha@1197: return false; sascha@1197: } sascha@1197: sascha@1197: int lineSkipCount; sascha@1197: try { sascha@1197: if ((lineSkipCount = Integer.parseInt(line)) < 0) { sascha@1197: throw new IllegalArgumentException(lineSkipCount + " < 0"); sascha@1197: } sascha@1197: } sascha@1197: catch (NumberFormatException nfe) { sascha@1197: log.warn( sascha@1197: "line 5 is not an positive integer."); sascha@1197: return false; sascha@1197: } sascha@1197: sascha@1197: int skip = lineSkipCount; sascha@1197: sascha@1196: while ((line = in.readLine()) != null) { sascha@1197: if (skip > 0) { sascha@1197: --skip; sascha@1196: continue; sascha@1196: } sascha@1197: double km; sascha@1197: try { sascha@1197: km = kmFormat.extractKm(line); sascha@1197: } sascha@1197: catch (NumberFormatException iae) { sascha@1197: log.warn("cannot extract km in line + " + in.getLineNumber()); sascha@1197: return false; sascha@1197: } sascha@1197: sascha@1197: Double station = Double.valueOf(km); sascha@1197: sascha@1197: Map kmData = data.get(station); sascha@1197: sascha@1197: if (kmData == null) { sascha@1197: log.debug("found new km: " + station); sascha@1197: kmData = new TreeMap(); sascha@1197: data.put(station, kmData); sascha@1197: } sascha@1197: sascha@1197: try { sascha@1197: if (!dataFormat.extractData(line, kmData)) { sascha@1197: skip = lineSkipCount; sascha@1197: } sascha@1197: } sascha@1197: catch (NumberFormatException nfe) { sascha@1197: log.warn("cannot extract data from line " + in.getLineNumber()); sascha@1197: return false; sascha@1197: } sascha@1196: } sascha@1196: } sascha@1196: catch (IOException ioe) { sascha@1196: log.error(ioe); sascha@1196: return false; sascha@1196: } sascha@1196: finally { sascha@1196: if (in != null) { sascha@1196: try { sascha@1196: in.close(); sascha@1196: } sascha@1196: catch (IOException ioe) { sascha@1196: log.error(ioe); sascha@1196: } sascha@1196: } sascha@1196: } sascha@1196: sascha@1196: return true; sascha@1196: } sascha@1196: sascha@1196: public void reset() { sascha@1196: data.clear(); sascha@1196: } sascha@1196: sascha@1196: public static void parsePRFs(File root) { sascha@1196: sascha@1196: PRFParser parser = new PRFParser(); sascha@1196: sascha@1196: Stack stack = new Stack(); sascha@1196: stack.push(root); sascha@1196: sascha@1196: while (!stack.empty()) { sascha@1196: File file = stack.pop(); sascha@1196: if (file.isDirectory()) { sascha@1196: File [] files = file.listFiles(); sascha@1196: if (files != null) { sascha@1196: for (File f: files) { sascha@1196: stack.push(f); sascha@1196: } sascha@1196: } sascha@1196: } sascha@1196: else if (file.isFile() sascha@1196: && file.getName().toLowerCase().endsWith(".prf") sascha@1196: ) { sascha@1196: parser.reset(); sascha@1196: boolean success = parser.parse(file); sascha@1196: log.info("parsing " + (success ? "succeeded" : "failed")); sascha@1196: } sascha@1196: } sascha@1196: } sascha@1196: sascha@1196: public static void main(String [] args) { sascha@1196: sascha@1196: for (String arg: args) { sascha@1196: parsePRFs(new File(arg)); sascha@1196: } sascha@1196: } sascha@1196: } sascha@1196: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :