view flys-backend/src/main/java/de/intevation/flys/importer/ImportRiver.java @ 2809:f283212966e8

Finished work on MINFO bed heights (single). flys-backend/trunk@4221 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Ingo Weinzierl <ingo.weinzierl@intevation.de>
date Thu, 12 Apr 2012 10:42:46 +0000
parents 33f40b23edd8
children 04eeb45df27b
line wrap: on
line source
package de.intevation.flys.importer;

import java.math.BigDecimal;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.HashSet;
import java.util.ArrayList;
import java.util.Date;
import java.util.Calendar;

import java.io.File;
import java.io.IOException;

import java.sql.SQLException;

import org.apache.log4j.Logger;

import de.intevation.artifacts.common.utils.FileTools;
import de.intevation.artifacts.common.utils.FileTools.HashedFile;

import de.intevation.flys.model.River;
import de.intevation.flys.model.Unit;

import de.intevation.flys.importer.parsers.BedHeightEpochParser;
import de.intevation.flys.importer.parsers.BedHeightSingleParser;
import de.intevation.flys.importer.parsers.PRFParser;
import de.intevation.flys.importer.parsers.HYKParser;
import de.intevation.flys.importer.parsers.AnnotationsParser;
import de.intevation.flys.importer.parsers.AnnotationClassifier;
import de.intevation.flys.importer.parsers.PegelGltParser;
import de.intevation.flys.importer.parsers.WstParser;

import org.hibernate.Session;
import org.hibernate.Query;
import org.hibernate.exception.ConstraintViolationException;

public class ImportRiver
{
    private static Logger log = Logger.getLogger(ImportRiver.class);

    public static final String PEGEL_GLT = "PEGEL.GLT";

    public static final String FIXATIONS = "Fixierungen";

    public static final String EXTRA_LONGITUDINALS =
        "Zus.L\u00e4ngsschnitte";

    public static final String [] OFFICIAL_LINES_FOLDERS = {
        "Basisdaten",
        "Fixierungen" };

    public static final String OFFICIAL_LINES =
        "Amtl_Linien.wst";

    public static final String FLOOD_WATER = "HW-Marken";

    public static final String FLOOD_PROTECTION =
        "HW-Schutzanlagen";

    public static final String MINFO_DIR = "Morphologie";

    public static final String BED_HEIGHT_DIR = "Sohlhoehen";

    public static final String BED_HEIGHT_SINGLE_DIR = "Einzeljahre";

    public static final String BED_HEIGHT_EPOCH_DIR = "Epochen";


    protected String name;

    protected File   wstFile;

    protected File   bbInfoFile;

    protected List<ImportGauge> gauges;

    protected List<ImportAnnotation> annotations;

    protected List<ImportHYK> hyks;

    protected List<ImportCrossSection> crossSections;

    protected List<ImportWst> extraWsts;

    protected List<ImportWst> fixations;

    protected List<ImportWst> officialLines;

    protected List<ImportWst> floodWater;

    protected List<ImportWst> floodProtection;

    protected List<ImportBedHeightSingle> bedHeightSingles;

    protected List<ImportBedHeightEpoch> bedHeightEpochs;

    protected ImportWst wst;

    protected ImportUnit wstUnit;

    protected AnnotationClassifier annotationClassifier;

    protected River peer;

    public ImportRiver() {
        hyks            = new ArrayList<ImportHYK>();
        crossSections   = new ArrayList<ImportCrossSection>();
        extraWsts       = new ArrayList<ImportWst>();
        fixations       = new ArrayList<ImportWst>();
        officialLines   = new ArrayList<ImportWst>();
        floodWater      = new ArrayList<ImportWst>();
        floodProtection = new ArrayList<ImportWst>();
    }

    public ImportRiver(
        String               name,
        File                 wstFile,
        File                 bbInfoFile,
        AnnotationClassifier annotationClassifier
    ) {
        this();
        this.name                 = name;
        this.wstFile              = wstFile;
        this.bbInfoFile           = bbInfoFile;
        this.annotationClassifier = annotationClassifier;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public File getWstFile() {
        return wstFile;
    }

    public void setWstFile(File wstFile) {
        this.wstFile = wstFile;
    }

    public File getBBInfo() {
        return bbInfoFile;
    }

    public void setBBInfo(File bbInfoFile) {
        this.bbInfoFile = bbInfoFile;
    }

    public ImportWst getWst() {
        return wst;
    }

    public void setWst(ImportWst wst) {
        this.wst = wst;
    }

    public File getMinfoDir() {
        File riverDir  = wstFile.getParentFile().getParentFile().getParentFile();
        return new File(riverDir, MINFO_DIR);
    }

    public void parseDependencies() throws IOException {
        parseGauges();
        parseAnnotations();
        parsePRFs();
        parseHYKs();
        parseWst();
        parseExtraWsts();
        parseFixations();
        parseOfficialLines();
        parseFloodWater();
        parseFloodProtection();
        parseBedHeight();
    }

    public void parseFloodProtection() throws IOException {
        if (Config.INSTANCE.skipFloodProtection()) {
            log.info("skip parsing flood protection");
            return;
        }

        log.info("Parse flood protection wst file");

        File riverDir = wstFile.getParentFile().getParentFile();

        File dir = FileTools.repair(new File(riverDir, FLOOD_PROTECTION));

        if (!dir.isDirectory() || !dir.canRead()) {
            log.info("no directory '" + dir + "' found");
            return;
        }

        File [] files = dir.listFiles();

        if (files == null) {
            log.warn("cannot read '" + dir + "'");
            return;
        }

        for (File file: files) {
            if (!file.isFile() || !file.canRead()) {
                continue;
            }
            String name = file.getName().toLowerCase();
            if (!(name.endsWith(".zus") || name.endsWith(".wst"))) {
                continue;
            }
            log.info("found file '" + file.getName() + "'");
            WstParser wstParser = new WstParser();
            wstParser.parse(file);
            ImportWst iw = wstParser.getWst();
            iw.setKind(5);
            iw.setDescription(FLOOD_PROTECTION + "/" + iw.getDescription());
            floodProtection.add(iw);
        }
    }


    public void parseBedHeight() throws IOException {
        if (Config.INSTANCE.skipBedHeight()) {
            log.info("skip parsing bed height.");
            return;
        }

        log.info("Parse bed height.");

        File minfoDir     = getMinfoDir();
        File bedHeightDir = new File(minfoDir, BED_HEIGHT_DIR);
        File singlesDir   = new File(bedHeightDir, BED_HEIGHT_SINGLE_DIR);
        File epochDir     = new File(bedHeightDir, BED_HEIGHT_EPOCH_DIR);

        parseBedHeightSingles(singlesDir);
        //parseBedHeightEpochs(epochDir);

        log.info("Finished parsing bed heights.");
    }


    protected void parseBedHeightSingles(File dir) throws IOException {
        log.debug("Parse bed height singles");

        File[] files = dir.listFiles();

        if (files == null) {
            log.warn("Cannot parse directory '" + dir + "'");
            return;
        }

        BedHeightSingleParser parser = new BedHeightSingleParser();

        for (File file: files) {
            parser.parse(file);
        }

        bedHeightSingles = parser.getBedHeights();
    }


    protected void parseBedHeightEpochs(File dir) throws IOException {
        log.debug("Parse bed height epochs");

        File[] files = dir.listFiles();

        if (files == null) {
            log.warn("Cannot parse directory '" + dir + "'");
            return;
        }

        BedHeightEpochParser parser = new BedHeightEpochParser();

        for (File file: files) {
            parser.parse(file);
        }

        bedHeightEpochs = parser.getBedHeights();
    }


    public void parseFloodWater() throws IOException {
        if (Config.INSTANCE.skipFloodWater()) {
            log.info("skip parsing flod water");
            return;
        }

        log.info("Parse flood water wst file");

        File riverDir = wstFile.getParentFile().getParentFile();

        File dir = FileTools.repair(new File(riverDir, FLOOD_WATER));

        if (!dir.isDirectory() || !dir.canRead()) {
            log.info("no directory '" + dir + "' found");
            return;
        }

        File [] files = dir.listFiles();

        if (files == null) {
            log.warn("cannot read '" + dir + "'");
            return;
        }

        for (File file: files) {
            if (!file.isFile() || !file.canRead()) {
                continue;
            }
            String name = file.getName().toLowerCase();
            if (!(name.endsWith(".zus") || name.endsWith(".wst"))) {
                continue;
            }
            log.info("found file '" + file.getName() + "'");
            WstParser wstParser = new WstParser();
            wstParser.parse(file);
            ImportWst iw = wstParser.getWst();
            iw.setKind(4);
            iw.setDescription(FLOOD_WATER + "/" + iw.getDescription());
            floodWater.add(iw);
        }
    }

    public void parseOfficialLines() throws IOException {
        if (Config.INSTANCE.skipOfficialLines()) {
            log.info("skip parsing official lines");
            return;
        }

        log.info("Parse official wst files");

        File riverDir = wstFile.getParentFile().getParentFile();

        for (String folder: OFFICIAL_LINES_FOLDERS) {
            File dir = FileTools.repair(new File(riverDir, folder));

            if (!dir.isDirectory() || !dir.canRead()) {
                log.info("no directory '" + folder + "' found");
                continue;
            }

            File file = FileTools.repair(new File(dir, OFFICIAL_LINES));
            if (!file.isFile() || !file.canRead()) {
                log.warn("no official lines wst file found");
                continue;
            }
            log.debug("Found WST file: " + file);

            WstParser wstParser = new WstParser();
            wstParser.parse(file);
            ImportWst iw = wstParser.getWst();
            iw.setKind(3);
            iw.setDescription(folder + "/" + iw.getDescription());
            officialLines.add(iw);
        } // for all folders

    }

    public void parseFixations() throws IOException {
        if (Config.INSTANCE.skipFixations()) {
            log.info("skip parsing fixations");
            return;
        }

        log.info("Parse fixation wst files");

        File riverDir = wstFile.getParentFile().getParentFile();

        File fixDir = FileTools.repair(
            new File(riverDir, FIXATIONS));

        if (!fixDir.isDirectory() || !fixDir.canRead()) {
            log.info("no fixation wst file directory found");
            return;
        }

        File [] files = fixDir.listFiles();

        if (files == null) {
            log.warn("cannot read fixations wst file directory");
            return;
        }

        for (File file: files) {
            if (!file.isFile() || !file.canRead()) {
                continue;
            }
            String name = file.getName().toLowerCase();
            if (!name.endsWith(".wst")) {
                continue;
            }
            log.debug("Found WST file: " + file);

            WstParser wstParser = new WstParser();
            wstParser.parse(file);
            ImportWst iw = wstParser.getWst();
            iw.setKind(2);
            iw.setDescription(FIXATIONS+ "/" + iw.getDescription());
            fixations.add(iw);
        }
    }

    public void parseExtraWsts() throws IOException {
        if (Config.INSTANCE.skipExtraWsts()) {
            log.info("skip parsing extra WST files");
            return;
        }

        log.info("Parse extra longitudinal wst files");

        File riverDir = wstFile.getParentFile().getParentFile();

        File extraDir = FileTools.repair(
            new File(riverDir, EXTRA_LONGITUDINALS));

        if (!extraDir.isDirectory() || !extraDir.canRead()) {
            log.info("no extra longitudinal wst file directory found");
            return;
        }

        File [] files = extraDir.listFiles();

        if (files == null) {
            log.warn("cannot read extra longitudinal wst file directory");
            return;
        }

        for (File file: files) {
            if (!file.isFile() || !file.canRead()) {
                continue;
            }
            String name = file.getName().toLowerCase();
            if (!(name.endsWith(".zus") || name.endsWith(".wst"))) {
                continue;
            }
            log.debug("Found WST file: " + file);

            WstParser wstParser = new WstParser();
            wstParser.parse(file);
            ImportWst iw = wstParser.getWst();
            iw.setKind(1);
            iw.setDescription(EXTRA_LONGITUDINALS + "/" + iw.getDescription());
            extraWsts.add(iw);
        }

    }

    public void parseWst() throws IOException {
        if (Config.INSTANCE.skipWst()) {
            log.info("skip parsing WST file");
            return;
        }

        WstParser wstParser = new WstParser();
        wstParser.parse(wstFile);
        wst = wstParser.getWst();
    }

    public void parseGauges() throws IOException {
        if (Config.INSTANCE.skipGauges()) {
            log.info("skip parsing gauges");
            return;
        }

        File gltFile = new File(wstFile.getParentFile(), PEGEL_GLT);
        gltFile = FileTools.repair(gltFile);

        if (!gltFile.isFile() || !gltFile.canRead()) {
            log.warn("cannot read gauges from '" + gltFile + "'");
            return;
        }

        PegelGltParser pgltp = new PegelGltParser();
        pgltp.parse(gltFile);

        gauges = pgltp.getGauges();

        for (ImportGauge gauge: gauges) {
            gauge.parseDependencies();
        }
    }

    public void parseAnnotations() throws IOException {
        if (Config.INSTANCE.skipAnnotations()) {
            log.info("skip parsing annotations");
            return;
        }

        File riverDir = wstFile.getParentFile().getParentFile();
        AnnotationsParser aparser =
            new AnnotationsParser(annotationClassifier);
        aparser.parse(riverDir);

        annotations = aparser.getAnnotations();
    }

    public void parseHYKs() {
        if (Config.INSTANCE.skipHYKs()) {
            log.info("skip parsing HYK files");
            return;
        }

        log.info("looking for HYK files");
        HYKParser parser = new HYKParser();
        File riverDir = wstFile
            .getParentFile()  // Basisdaten
            .getParentFile()  // Hydrologie
            .getParentFile(); // <river>

        parser.parseHYKs(riverDir, new HYKParser.Callback() {

            Set<HashedFile> hfs = new HashSet<HashedFile>();

            @Override
            public boolean hykAccept(File file) {
                HashedFile hf = new HashedFile(file);
                boolean success = hfs.add(hf);
                if (!success) {
                    log.warn("HYK file '" + file + "' seems to be a duplicate.");
                }
                return success;
            }

            @Override
            public void hykParsed(HYKParser parser) {
                log.debug("callback from HYK parser");
                ImportHYK hyk = parser.getHYK();
                hyk.setRiver(ImportRiver.this);
                hyks.add(hyk);
            }
        });
    }

    public void parsePRFs() {
        if (Config.INSTANCE.skipPRFs()) {
            log.info("skip parsing PRFs");
            return;
        }

        log.info("looking for PRF files");
        PRFParser parser = new PRFParser();
        File riverDir = wstFile
            .getParentFile()  // Basisdaten
            .getParentFile()  // Hydrologie
            .getParentFile(); // <river>

        parser.parsePRFs(riverDir, new PRFParser.Callback() {

            Set<HashedFile> prfs = new HashSet<HashedFile>();

            @Override
            public boolean prfAccept(File file) {
                HashedFile hf = new HashedFile(file);
                boolean success = prfs.add(hf);
                if (!success) {
                    log.warn("PRF file '" + file + "' seems to be a duplicate.");
                }
                return success;
            }

            @Override
            public void prfParsed(PRFParser parser) {
                log.debug("callback from PRF parser");

                String  description = parser.getDescription();
                Integer year        = parser.getYear();
                ImportTimeInterval ti = year != null
                    ? new ImportTimeInterval(yearToDate(year))
                    : null;

                List<ImportCrossSectionLine> lines =
                    new ArrayList<ImportCrossSectionLine>();

                for (Map.Entry<Double, List<XY>> entry: parser.getData().entrySet()) {
                    BigDecimal km     = new BigDecimal(entry.getKey());
                    List<XY>   points = entry.getValue();
                    lines.add(new ImportCrossSectionLine(km, points));
                }

                crossSections.add(new ImportCrossSection(
                    ImportRiver.this, description, ti, lines));
            }
        });
    }

    public static Date yearToDate(int year) {
        Calendar cal = Calendar.getInstance();
        cal.set(year, 5, 15, 12, 0, 0);
        long ms = cal.getTimeInMillis();
        cal.setTimeInMillis(ms - ms%1000);
        return cal.getTime();
    }

    public void storeDependencies() {
        storeWstUnit();
        storeAnnotations();
        storeHYKs();
        storeCrossSections();
        storeGauges();
        storeWst();
        storeExtraWsts();
        storeFixations();
        storeOfficialLines();
        storeFloodWater();
        storeFloodProtection();
        storeBedHeight();
    }

    public void storeWstUnit() {
        if (wst == null) {
            wstUnit = new ImportUnit("NN + m");
        }
        else {
            wstUnit = wst.getUnit();
        }
    }

    public void storeHYKs() {
        if (!Config.INSTANCE.skipHYKs()) {
            log.info("store HYKs");
            getPeer();
            for (ImportHYK hyk: hyks) {
                hyk.storeDependencies();
            }
        }
    }

    public void storeCrossSections() {
        if (!Config.INSTANCE.skipPRFs()) {
            log.info("store cross sections");
            getPeer();
            for (ImportCrossSection crossSection: crossSections) {
                crossSection.storeDependencies();
            }
        }
    }

    public void storeWst() {
        if (!Config.INSTANCE.skipWst()) {
            River river = getPeer();
            wst.storeDependencies(river);
        }
    }

    public void storeFixations() {
        if (!Config.INSTANCE.skipFixations()) {
            log.info("store fixation wsts");
            River river = getPeer();
            for (ImportWst wst: fixations) {
                log.debug("name: " + wst.getDescription());
                wst.storeDependencies(river);
            }
        }
    }

    public void storeExtraWsts() {
        if (!Config.INSTANCE.skipExtraWsts()) {
            log.info("store extra wsts");
            River river = getPeer();
            for (ImportWst wst: extraWsts) {
                log.debug("name: " + wst.getDescription());
                wst.storeDependencies(river);
            }
        }
    }

    public void storeOfficialLines() {
        if (!Config.INSTANCE.skipOfficialLines()) {
            log.info("store official lines wsts");
            River river = getPeer();
            for (ImportWst wst: officialLines) {
                log.debug("name: " + wst.getDescription());
                wst.storeDependencies(river);
            }
        }
    }

    public void storeFloodWater() {
        if (!Config.INSTANCE.skipFloodWater()) {
            log.info("store flood water wsts");
            River river = getPeer();
            for (ImportWst wst: floodWater) {
                log.debug("name: " + wst.getDescription());
                wst.storeDependencies(river);
            }
        }
    }

    public void storeFloodProtection() {
        if (!Config.INSTANCE.skipFloodProtection()) {
            log.info("store flood protection wsts");
            River river = getPeer();
            for (ImportWst wst: floodProtection) {
                log.debug("name: " + wst.getDescription());
                wst.storeDependencies(river);
            }
        }
    }


    public void storeBedHeight() {
        if (!Config.INSTANCE.skipBedHeight()) {
            log.info("store bed heights");
            River river = getPeer();

            if (bedHeightSingles != null) {
                for (ImportBedHeightSingle single: bedHeightSingles) {
                    String desc = single.getDescription();

                    log.debug("name: " + desc);

                    try {
                        single.storeDependencies(river);
                    }
                    catch (SQLException sqle) {
                        log.error("File '" + desc + "' is broken!");
                    }
                    catch (ConstraintViolationException cve) {
                        log.error("File '" + desc + "' is broken!");
                    }
                }
            }
            else {
                log.info("No single bed heights to store.");
            }

            if (bedHeightEpochs != null) {
                for (ImportBedHeightEpoch epoch: bedHeightEpochs) {
                    log.debug("name: " + epoch.getDescription());
                    epoch.storeDependencies(river);
                }
            }
            else {
                log.info("No epoch bed heights to store.");
            }
        }
    }

    public void storeAnnotations() {
        if (!Config.INSTANCE.skipAnnotations()) {
            River river = getPeer();
            for (ImportAnnotation annotation: annotations) {
                annotation.getPeer(river);
            }
        }
    }

    public void storeGauges() {
        if (!Config.INSTANCE.skipGauges()) {
            log.info("store gauges:");
            River river = getPeer();
            Session session = ImporterSession.getInstance()
                .getDatabaseSession();
            for (ImportGauge gauge: gauges) {
                log.info("\tgauge: " + gauge.getName());
                gauge.storeDependencies(river);
                ImporterSession.getInstance().getDatabaseSession();
                session.flush();
            }
        }
    }

    public River getPeer() {
        if (peer == null) {
            Session session = ImporterSession.getInstance().getDatabaseSession();
            Query query = session.createQuery("from River where name=:name");

            Unit u = wstUnit.getPeer();

            query.setString("name", name);
            List<River> rivers = query.list();
            if (rivers.isEmpty()) {
                log.info("Store new river '" + name + "'");
                peer = new River(name, u);
                session.save(peer);
            }
            else {
                peer = rivers.get(0);
            }
        }
        return peer;
    }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org