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