view artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/BedQualityD50TimeRangeConfig.java @ 9469:6acd22e86951

Improvements on Config-Files
author gernotbelger
date Tue, 04 Sep 2018 16:42:03 +0200
parents
children 787fc085459b
line wrap: on
line source
/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
 * Software engineering by
 *  Björnsen Beratende Ingenieure GmbH
 *  Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
 *
 * This file is Free Software under the GNU AGPL (>=v3)
 * and comes with ABSOLUTELY NO WARRANTY! Check out the
 * documentation coming with Dive4Elements River for details.
 */
package org.dive4elements.river.artifacts.sinfo.tkhstate;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.dive4elements.artifacts.common.utils.Config;
import org.dive4elements.river.artifacts.model.Calculation;
import org.dive4elements.river.artifacts.model.DateRange;
import org.dive4elements.river.model.River;

/**
 * Represents the contents of the 'bedheights.properties' files.
 *
 * @author Gernot Belger
 */
public final class BedQualityD50TimeRangeConfig {

    private static final String CONFIG_FILE = "d50_sohlkorndurchmesser_%s.properties";

    private final Map<String, DateRange> cache = new HashMap<>();

    private static BedQualityD50TimeRangeConfig INSTANCE = new BedQualityD50TimeRangeConfig();

    public static synchronized DateRange getDefaults(final River river, final int soundingYear, final Calculation problems) {
        return INSTANCE.getBedHeightDefaultsForRiver(river, soundingYear, problems);
    }

    private synchronized DateRange getBedHeightDefaultsForRiver(final River river, final int soundingYear, final Calculation problems) {
        final String rivername = river.getName();
        final String cacheKey = new StringBuilder().append(rivername).append(";").append(soundingYear).toString();
        if (!this.cache.containsKey(cacheKey)) {
            final DateRange range = loadBedHeightDefaultsForRiver(river, soundingYear, problems);
            this.cache.put(cacheKey, range);
            return range;
        }
        return this.cache.get(cacheKey);
    }

    private static DateRange loadBedHeightDefaultsForRiver(final River river, final int soundingYear, final Calculation problems) {
        final String rivername = river.getName();
        final File configDir = Config.getModulesConfigDirectory();

        final String filename = String.format(CONFIG_FILE, rivername);

        final File file = new File(configDir, filename);

        if (!file.canRead() && !file.isFile()) {
            return null; // no config-file specified or spelling mistake etc. (not necessarily an error)
        }

        try (final BufferedReader reader = new BufferedReader(new FileReader(file))) {

            String line;
            while ((line = reader.readLine()) != null) {
                if ((line = line.trim()).length() == 0 || line.startsWith("#")) {
                    continue;
                }

                final String[] parts = line.split(";");

                if (parts.length != 4) {
                    throw new Exception("Invalid number of Tokens; should be 4!");
                }

                final CalRange range = new CalRange(parseInput(parts[0]), parseInput(parts[1]), parseInput(parts[2]), parseInput(parts[3]));
                if (range.isSoundingYearInRange(soundingYear)) {
                    return new DateRange(range.getStartTimeQuery(), range.getEndTimeQuery());
                }
            }
            return null;
        }
        catch (final Exception e) {
            e.printStackTrace();
            problems.addProblem("sinfo.bedqualityd50config.configfile.loaderror", CONFIG_FILE, e.getMessage());
            return null;
        }
    }

    private static Integer parseInput(final String value) throws Exception {
        if (value.toUpperCase().equals("MIN") || value.toUpperCase().equals("MAX"))
            return null;
        try {
            return Integer.valueOf(value);
        }
        catch (final NumberFormatException e) {
            throw new Exception("Invalid input; should be year ('yyyy') or 'MIN' or 'MAX'");
        }
    }

    private static class CalRange {
        private final long startTimeSounding;
        private final long endTimeSounding;

        private final long startTimeQuery;
        private final long endTimeQuery;

        private final static Calendar cal = Calendar.getInstance();

        private Date getStartTimeQuery() {
            return new Date(this.startTimeQuery);
        }

        private Date getEndTimeQuery() {
            return new Date(this.endTimeQuery);
        }

        private CalRange(final Integer startYearSounding, final Integer endYearSounding, final Integer startYearQuery, final Integer endYearQuery) {

            this.startTimeSounding = 1l;// (startYearSounding != null) ? getLongValForYear(startYearSounding, 0, 1) :
                                        // BedQualityD50KmValueFinder.MIN_DATE.getTime();
            this.startTimeQuery = 1l;// (startYearQuery != null) ? getLongValForYear(startYearQuery, 0, 1) : BedQualityD50KmValueFinder.MIN_DATE.getTime();
            this.endTimeSounding = 1l;// (endYearSounding != null) ? getLongValForYear(endYearSounding, 11, 31) :
                                      // BedQualityD50KmValueFinder.MAX_DATE.getTime();
            this.endTimeQuery = 1l; // (endYearQuery != null) ? getLongValForYear(endYearQuery, 11, 31) : BedQualityD50KmValueFinder.MAX_DATE.getTime();

        }

        private long getLongValForYear(final int year, final int month0based, final int dayOfMonth) {
            cal.clear();
            cal.set(year, month0based, dayOfMonth);

            return cal.getTimeInMillis();
        }

        private boolean isSoundingYearInRange(final int soundingYear) {
            cal.clear();

            cal.set(soundingYear, 5, 5); // random date in the middle of the year

            final Long time = cal.getTimeInMillis();

            if (time > this.startTimeSounding && time < this.endTimeSounding)
                return true;

            return false;
        }

    }

}

http://dive4elements.wald.intevation.org