sascha@1215: package de.intevation.flys.importer.parsers; sascha@1215: sascha@1215: import de.intevation.flys.importer.ImportHYKFlowZoneType; sascha@1215: sascha@1215: import java.io.File; sascha@1215: import java.io.IOException; sascha@1215: import java.io.FileInputStream; sascha@1215: import java.io.InputStreamReader; sascha@1215: import java.io.LineNumberReader; sascha@1215: sascha@1215: import java.util.HashMap; sascha@1215: import java.util.Map; sascha@1215: sascha@1215: import java.math.BigDecimal; sascha@1215: sascha@1215: import org.apache.log4j.Logger; sascha@1215: sascha@1215: public class HYKParser sascha@1215: { sascha@1215: private static Logger log = Logger.getLogger(HYKParser.class); sascha@1215: sascha@1215: public static enum State { sascha@1215: LINE_1, LINE_2, LINE_3, LINE_4, LINE_5, LINE_6 sascha@1215: }; sascha@1215: sascha@1215: private static final String ENCODING = "ISO-8859-1"; sascha@1215: sascha@1215: protected Map flowZoneTypes; sascha@1215: sascha@1215: public HYKParser() { sascha@1215: flowZoneTypes = new HashMap(); sascha@1215: } sascha@1215: sascha@1215: public boolean parse(File file) { sascha@1215: sascha@1215: log.info("Parsing HYK file '" + file + "'"); sascha@1215: sascha@1215: LineNumberReader in = null; sascha@1215: sascha@1215: try { sascha@1215: in = sascha@1215: new LineNumberReader( sascha@1215: new InputStreamReader( sascha@1215: new FileInputStream(file), ENCODING)); sascha@1215: sascha@1215: String line; sascha@1215: sascha@1215: State state = State.LINE_1; sascha@1215: sascha@1215: int numFormations = 0; sascha@1215: sascha@1215: BigDecimal km = null; sascha@1215: BigDecimal top = null; sascha@1215: BigDecimal bottom = null; sascha@1215: BigDecimal distanceVL = null; sascha@1215: BigDecimal distanceHF = null; sascha@1215: BigDecimal distanceVR = null; sascha@1215: sascha@1215: Integer year = null; sascha@1215: int numZones = 0; sascha@1215: sascha@1215: ImportHYKFlowZoneType [] fzts = null; sascha@1215: BigDecimal [] coords = null; sascha@1215: int coordPos = 0; sascha@1215: sascha@1215: while ((line = in.readLine()) != null) { sascha@1215: if ((line = line.trim()).length() == 0) { sascha@1215: continue; sascha@1215: } sascha@1215: if (line.startsWith("*")) { sascha@1215: continue; sascha@1215: } sascha@1215: String [] parts = line.split("\\s+"); sascha@1215: sascha@1215: switch (state) { sascha@1215: case LINE_1: sascha@1215: if (parts.length < 2) { sascha@1215: log.error("not enough elements in line " + sascha@1215: in.getLineNumber()); sascha@1215: return false; sascha@1215: } sascha@1215: sascha@1215: if (parts.length == 2) { sascha@1215: // no year given sascha@1215: year = null; sascha@1215: } sascha@1215: else { sascha@1215: try { sascha@1215: year = Integer.valueOf(parts[1]); sascha@1215: } sascha@1215: catch (NumberFormatException nfe) { sascha@1215: log.error( sascha@1215: "year is not an integer in line " + sascha@1215: in.getLineNumber()); sascha@1215: return false; sascha@1215: } sascha@1215: } sascha@1215: try { sascha@1215: km = new BigDecimal(parts[0]); sascha@1215: numFormations = Integer.parseInt( sascha@1215: parts[parts.length > 2 ? 2 : 1]); sascha@1215: } sascha@1215: catch (NumberFormatException nfe) { sascha@1215: log.error( sascha@1215: "parsing number of formations " + sascha@1215: "or km failed in line " + in.getLineNumber()); sascha@1215: return false; sascha@1215: } sascha@1215: // TODO: Store HYKEntry sascha@1215: sascha@1215: state = State.LINE_2; sascha@1215: break; sascha@1215: sascha@1215: case LINE_2: sascha@1215: if (parts.length < 3) { sascha@1215: log.error("not enough elements in line " + sascha@1215: in.getLineNumber()); sascha@1215: return false; sascha@1215: } sascha@1215: try { sascha@1215: numZones = Integer.parseInt(parts[0]); sascha@1215: bottom = new BigDecimal(parts[1]); sascha@1215: top = new BigDecimal(parts[2]); sascha@1215: } sascha@1215: catch (NumberFormatException nfe) { sascha@1215: log.error( sascha@1215: "parsing num zones, bottom or top height " + sascha@1215: "failed in line " + in.getLineNumber()); sascha@1215: return false; sascha@1215: } sascha@1215: state = State.LINE_3; sascha@1215: break; sascha@1215: sascha@1215: case LINE_3: sascha@1215: if (parts.length != numZones) { sascha@1215: log.error( sascha@1215: "number of flow zones mismatches " + sascha@1215: "in line " + in.getLineNumber()); sascha@1215: return false; sascha@1215: } sascha@1215: sascha@1215: fzts = new ImportHYKFlowZoneType[parts.length]; sascha@1215: for (int i = 0; i < fzts.length; ++i) { sascha@1215: fzts[i] = getFlowZoneType(parts[i]); sascha@1215: } sascha@1215: state = State.LINE_4; sascha@1215: break; sascha@1215: sascha@1215: case LINE_4: sascha@1215: try { sascha@1215: int N = Math.min(parts.length, coords.length); sascha@1215: for (coordPos = 0; coordPos < N; ++coordPos) { sascha@1215: coords[coordPos] = sascha@1215: new BigDecimal(parts[coordPos]); sascha@1215: } sascha@1215: } sascha@1215: catch (NumberFormatException nfe) { sascha@1215: log.error("cannot parse number in line " + sascha@1215: in.getLineNumber()); sascha@1215: return false; sascha@1215: } sascha@1215: state = State.LINE_5; sascha@1215: break; sascha@1215: sascha@1215: case LINE_5: sascha@1215: if (parts.length + coordPos < coords.length) { sascha@1215: log.error("not enough elements in line " + sascha@1215: in.getLineNumber()); sascha@1215: return false; sascha@1215: } sascha@1215: try { sascha@1215: for (int i = 0; sascha@1215: i < parts.length && coordPos < coords.length; sascha@1215: ++i, ++coordPos sascha@1215: ) { sascha@1215: coords[coordPos] = new BigDecimal(parts[i]); sascha@1215: } sascha@1215: } sascha@1215: catch (NumberFormatException nfe) { sascha@1215: log.error("cannot parse number in line " + sascha@1215: in.getLineNumber()); sascha@1215: return false; sascha@1215: } sascha@1215: state = State.LINE_6; sascha@1215: break; sascha@1215: sascha@1215: case LINE_6: sascha@1215: if (parts.length < 3) { sascha@1215: log.error("not enough elements in line " + sascha@1215: in.getLineNumber()); sascha@1215: return false; sascha@1215: } sascha@1215: try { sascha@1215: distanceVL = new BigDecimal(parts[0]); sascha@1215: distanceHF = new BigDecimal(parts[1]); sascha@1215: distanceVL = new BigDecimal(parts[2]); sascha@1215: } sascha@1215: catch (NumberFormatException nfe) { sascha@1215: log.error("cannot parse number in line " + sascha@1215: in.getLineNumber()); sascha@1215: return false; sascha@1215: } sascha@1215: // TODO: now we have enough information sascha@1215: // to store a formation. sascha@1215: sascha@1215: // continue with next formation. sascha@1215: state = --numFormations > 0 // formations left? sascha@1215: ? State.LINE_2 sascha@1215: : State.LINE_1; sascha@1215: break; sascha@1215: } sascha@1215: } sascha@1215: } sascha@1215: catch (IOException ioe) { sascha@1215: log.error(ioe); sascha@1215: return false; sascha@1215: } sascha@1215: finally { sascha@1215: if (in != null) { sascha@1215: try { sascha@1215: in.close(); sascha@1215: } sascha@1215: catch (IOException ioe) { sascha@1215: log.error(ioe); sascha@1215: } sascha@1215: } sascha@1215: } sascha@1215: return true; sascha@1215: } sascha@1215: sascha@1215: protected ImportHYKFlowZoneType getFlowZoneType(String name) { sascha@1215: name = name.toUpperCase(); sascha@1215: ImportHYKFlowZoneType fzt = flowZoneTypes.get(name); sascha@1215: if (fzt == null) { sascha@1215: fzt = new ImportHYKFlowZoneType(name); sascha@1215: flowZoneTypes.put(name, fzt); sascha@1215: } sascha@1215: return fzt; sascha@1215: } sascha@1215: } sascha@1215: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :