sascha@186: package de.intevation.flys.importer; sascha@186: sascha@186: import java.util.HashMap; sascha@186: import java.util.TreeSet; sascha@186: import java.util.List; sascha@186: import java.util.ArrayList; sascha@186: sascha@186: import java.io.IOException; sascha@186: import java.io.File; sascha@186: import java.io.LineNumberReader; sascha@186: import java.io.InputStreamReader; sascha@186: import java.io.FileInputStream; sascha@186: sascha@189: import java.math.BigDecimal; sascha@189: sascha@186: import org.apache.log4j.Logger; sascha@186: sascha@186: import de.intevation.flys.utils.FileTools; sascha@186: sascha@186: public class AnnotationsParser sascha@186: { sascha@186: private static Logger log = Logger.getLogger(AnnotationsParser.class); sascha@186: sascha@186: public static final String ENCODING = "ISO-8859-1"; sascha@186: sascha@186: public static final String [] TO_SCAN = { sascha@186: "Basisdaten", sascha@186: "Streckendaten" sascha@186: }; sascha@186: sascha@186: protected HashMap attributes; sascha@186: protected HashMap positions; sascha@186: protected TreeSet annotations; sascha@765: protected AnnotationClassifier classifier; sascha@186: sascha@186: public AnnotationsParser() { sascha@765: this(null); sascha@765: } sascha@765: sascha@765: public AnnotationsParser(AnnotationClassifier classifier) { sascha@186: attributes = new HashMap(); sascha@186: positions = new HashMap(); sascha@186: annotations = new TreeSet(); sascha@765: this.classifier = classifier; sascha@186: } sascha@186: sascha@186: public void parseFile(File file) throws IOException { sascha@186: log.info("parsing km file: '" + file + "'"); sascha@765: sascha@765: ImportAnnotationType defaultIAT = null; sascha@765: sascha@765: if (classifier != null) { sascha@765: defaultIAT = classifier.classifyFile( sascha@765: file.getName(), sascha@765: classifier.getDefaultType()); sascha@765: } sascha@765: sascha@186: LineNumberReader in = null; sascha@186: try { sascha@186: in = sascha@186: new LineNumberReader( sascha@186: new InputStreamReader( sascha@186: new FileInputStream(file), ENCODING)); sascha@186: sascha@186: String line = null; sascha@186: while ((line = in.readLine()) != null) { sascha@186: if ((line = line.trim()).length() == 0 sascha@186: || line.startsWith("*")) { sascha@186: continue; sascha@186: } sascha@186: sascha@186: String [] parts = line.split("\\s*;\\s*"); sascha@186: sascha@186: if (parts.length < 3) { sascha@186: log.warn("not enough columns in line " sascha@186: + in.getLineNumber()); sascha@186: continue; sascha@186: } sascha@186: sascha@186: ImportPosition position = positions.get(parts[0]); sascha@186: if (position == null) { sascha@186: position = new ImportPosition(parts[0]); sascha@186: positions.put(parts[0], position); sascha@186: } sascha@186: sascha@186: ImportAttribute attribute = attributes.get(parts[1]); sascha@186: if (attribute == null) { sascha@186: attribute = new ImportAttribute(parts[1]); sascha@186: attributes.put(parts[1], attribute); sascha@186: } sascha@186: sascha@186: String [] r = parts[2].replace(",", ".").split("\\s*#\\s*"); sascha@186: sascha@189: BigDecimal from, to; sascha@186: sascha@186: try { sascha@189: from = new BigDecimal(r[0]); sascha@189: to = r.length < 2 ? null : new BigDecimal(r[1]); sascha@189: if (to != null && from.compareTo(to) > 0) { sascha@464: BigDecimal t = from; from = to; to = t; sascha@186: } sascha@186: } sascha@186: catch (NumberFormatException nfe) { sascha@186: log.warn("invalid number in line " + in.getLineNumber()); sascha@186: continue; sascha@186: } sascha@186: sascha@759: ImportEdge edge = null; sascha@759: sascha@759: if (parts.length == 4) { // Only 'Unterkante' sascha@759: try { sascha@759: edge = new ImportEdge( sascha@759: null, sascha@759: new BigDecimal(parts[3].trim().replace(',', '.'))); sascha@759: } sascha@759: catch (NumberFormatException nfe) { sascha@759: log.warn("cannot parse 'Unterkante' in line " + sascha@759: in.getLineNumber()); sascha@759: } sascha@759: } sascha@759: else if (parts.length > 4) { // 'Unterkante' and 'Oberkante' sascha@759: String bottom = parts[3].trim().replace(',', '.'); sascha@759: String top = parts[4].trim().replace(',', '.'); sascha@759: try { sascha@759: BigDecimal b = bottom.length() == 0 sascha@759: ? null sascha@759: : new BigDecimal(bottom); sascha@759: BigDecimal t = top.length() == 0 sascha@759: ? null sascha@759: : new BigDecimal(top); sascha@759: edge = new ImportEdge(t, b); sascha@759: } sascha@759: catch (NumberFormatException nfe) { sascha@759: log.warn( sascha@759: "cannot parse 'Unterkante' or 'Oberkante' in line " sascha@759: + in.getLineNumber()); sascha@759: } sascha@759: } sascha@759: sascha@186: ImportRange range = new ImportRange(from, to); sascha@186: sascha@765: ImportAnnotationType type = classifier != null sascha@765: ? classifier.classifyDescription(line, defaultIAT) sascha@765: : null; sascha@763: sascha@186: ImportAnnotation annotation = new ImportAnnotation( sascha@763: attribute, position, range, edge, type); sascha@186: sascha@186: if (!annotations.add(annotation)) { sascha@771: log.warn("duplicated annotation '" + parts[0] + sascha@766: "' in line " + in.getLineNumber()); sascha@186: } sascha@186: } sascha@186: } sascha@186: finally { sascha@186: if (in != null) { sascha@186: in.close(); sascha@186: } sascha@186: } sascha@186: } sascha@186: sascha@186: public void parse(File root) throws IOException { sascha@186: sascha@186: for (String toScan: TO_SCAN) { sascha@186: File directory = FileTools.repair(new File(root, toScan)); sascha@186: if (!directory.isDirectory()) { sascha@186: log.warn("'" + directory + "' is not a directory."); sascha@186: continue; sascha@186: } sascha@186: File [] files = directory.listFiles(); sascha@186: if (files == null) { sascha@186: log.warn("cannot list directory '" + directory + "'"); sascha@186: continue; sascha@186: } sascha@186: sascha@186: for (File file: files) { sascha@186: if (file.isFile() && file.canRead() sascha@186: && file.getName().toLowerCase().endsWith(".km")) { sascha@186: parseFile(file); sascha@186: } sascha@186: } sascha@186: } // for all directories to scan sascha@186: } sascha@186: sascha@186: public List getAnnotations() { sascha@186: return new ArrayList(annotations); sascha@186: } sascha@186: } sascha@186: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :