9469
|
1 /** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde |
|
2 * Software engineering by |
|
3 * Björnsen Beratende Ingenieure GmbH |
|
4 * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt |
|
5 * |
|
6 * This file is Free Software under the GNU AGPL (>=v3) |
|
7 * and comes with ABSOLUTELY NO WARRANTY! Check out the |
|
8 * documentation coming with Dive4Elements River for details. |
|
9 */ |
|
10 package org.dive4elements.river.artifacts.sinfo.tkhstate; |
|
11 |
|
12 import java.io.File; |
9481
|
13 import java.io.IOException; |
9469
|
14 import java.util.Calendar; |
|
15 import java.util.Date; |
|
16 import java.util.HashMap; |
9481
|
17 import java.util.List; |
9469
|
18 import java.util.Map; |
|
19 |
|
20 import org.dive4elements.river.artifacts.model.Calculation; |
|
21 import org.dive4elements.river.artifacts.model.DateRange; |
9481
|
22 import org.dive4elements.river.artifacts.sinfo.tkhstate.TsvHelper.TsvReaderException; |
9469
|
23 import org.dive4elements.river.model.River; |
|
24 |
|
25 /** |
|
26 * Represents the contents of the 'bedheights.properties' files. |
|
27 * |
|
28 * @author Gernot Belger |
|
29 */ |
|
30 public final class BedQualityD50TimeRangeConfig { |
|
31 |
9481
|
32 private static final String CONFIG_FILE = "d50_sohlkorndurchmesser_%s.tsv"; |
9469
|
33 |
|
34 private final Map<String, DateRange> cache = new HashMap<>(); |
|
35 |
|
36 private static BedQualityD50TimeRangeConfig INSTANCE = new BedQualityD50TimeRangeConfig(); |
|
37 |
9481
|
38 public static class BedQualityParseException extends Exception { |
|
39 |
|
40 private static final long serialVersionUID = 1L; |
|
41 |
|
42 private BedQualityParseException(final String string) { |
|
43 super(string); |
|
44 } |
|
45 } |
|
46 |
|
47 public static synchronized DateRange getDefaults(final River river, final int soundingYear, final Calculation problems) |
|
48 throws BedQualityParseException, IOException, TsvReaderException { |
9469
|
49 return INSTANCE.getBedHeightDefaultsForRiver(river, soundingYear, problems); |
|
50 } |
|
51 |
9481
|
52 private synchronized DateRange getBedHeightDefaultsForRiver(final River river, final int soundingYear, final Calculation problems) |
|
53 throws BedQualityParseException { |
9469
|
54 final String rivername = river.getName(); |
|
55 final String cacheKey = new StringBuilder().append(rivername).append(";").append(soundingYear).toString(); |
|
56 if (!this.cache.containsKey(cacheKey)) { |
9481
|
57 final File file = TsvHelper.makeFile2(CONFIG_FILE, rivername); |
|
58 final File fileCheck = TsvHelper.checkFile(file); |
|
59 if (fileCheck == null) |
|
60 return null; // automatically dateRange min/max wil be taken |
|
61 |
|
62 List<String[]> results = null; |
|
63 try { |
|
64 results = TsvHelper.readTsv(file, 4); |
|
65 } |
|
66 catch (final TsvReaderException | IOException e) { |
|
67 problems.addProblem("sinfo.bedqualityd50config.configfile.loaderror", file.getPath(), e.getStackTrace()); |
|
68 } |
|
69 if (results != null) { |
|
70 for (final String[] line : results) { |
|
71 final CalRange range = new CalRange(parseInput(line[0]), parseInput(line[1]), parseInput(line[2]), parseInput(line[3])); |
|
72 if (range.isSoundingYearInRange(soundingYear)) { |
|
73 final DateRange dateRange = new DateRange(range.getStartTimeQuery(), range.getEndTimeQuery()); |
|
74 this.cache.put(cacheKey, dateRange); |
|
75 |
|
76 } |
|
77 } |
|
78 } |
|
79 problems.addProblem("sinfo.bedqualityd50config.configfile.loaderror", file.getPath(), |
|
80 " Die angegebene d50-sohlkorndurchmesser-config-file enthält keinen gültigen Bereich für das konfigurierte Peiljahr."); |
|
81 return null; |
9469
|
82 } |
|
83 return this.cache.get(cacheKey); |
|
84 } |
|
85 |
9481
|
86 private static Integer parseInput(final String raw) throws BedQualityParseException { |
|
87 final String value = raw.trim(); |
9469
|
88 if (value.toUpperCase().equals("MIN") || value.toUpperCase().equals("MAX")) |
|
89 return null; |
|
90 try { |
9481
|
91 |
9469
|
92 return Integer.valueOf(value); |
|
93 } |
|
94 catch (final NumberFormatException e) { |
9481
|
95 throw new BedQualityParseException("Invalid input; should be year ('yyyy') or 'MIN' or 'MAX'"); |
9469
|
96 } |
|
97 } |
|
98 |
|
99 private static class CalRange { |
|
100 private final long startTimeSounding; |
|
101 private final long endTimeSounding; |
|
102 |
|
103 private final long startTimeQuery; |
|
104 private final long endTimeQuery; |
|
105 |
|
106 private final static Calendar cal = Calendar.getInstance(); |
|
107 |
|
108 private Date getStartTimeQuery() { |
|
109 return new Date(this.startTimeQuery); |
|
110 } |
|
111 |
|
112 private Date getEndTimeQuery() { |
|
113 return new Date(this.endTimeQuery); |
|
114 } |
|
115 |
|
116 private CalRange(final Integer startYearSounding, final Integer endYearSounding, final Integer startYearQuery, final Integer endYearQuery) { |
|
117 |
9481
|
118 this.startTimeSounding = 1L;// (startYearSounding != null) ? getLongValForYear(startYearSounding, 0, 1) : |
9469
|
119 // BedQualityD50KmValueFinder.MIN_DATE.getTime(); |
9481
|
120 this.startTimeQuery = 1L;// (startYearQuery != null) ? getLongValForYear(startYearQuery, 0, 1) : BedQualityD50KmValueFinder.MIN_DATE.getTime(); |
|
121 this.endTimeSounding = 1L;// (endYearSounding != null) ? getLongValForYear(endYearSounding, 11, 31) : |
9469
|
122 // BedQualityD50KmValueFinder.MAX_DATE.getTime(); |
9481
|
123 this.endTimeQuery = 1L;// (endYearQuery != null) ? getLongValForYear(endYearQuery, 11, 31) : BedQualityD50KmValueFinder.MAX_DATE.getTime(); |
9469
|
124 |
|
125 } |
|
126 |
|
127 private long getLongValForYear(final int year, final int month0based, final int dayOfMonth) { |
|
128 cal.clear(); |
|
129 cal.set(year, month0based, dayOfMonth); |
|
130 |
|
131 return cal.getTimeInMillis(); |
|
132 } |
|
133 |
|
134 private boolean isSoundingYearInRange(final int soundingYear) { |
|
135 cal.clear(); |
|
136 |
|
137 cal.set(soundingYear, 5, 5); // random date in the middle of the year |
|
138 |
|
139 final Long time = cal.getTimeInMillis(); |
|
140 |
|
141 if (time > this.startTimeSounding && time < this.endTimeSounding) |
|
142 return true; |
|
143 |
|
144 return false; |
|
145 } |
|
146 |
|
147 } |
|
148 |
|
149 } |