comparison artifacts/src/main/java/org/dive4elements/river/artifacts/services/DynamicMainValuesTimeRangeDeterminationService.java @ 9409:38201f5b0dd9

Changed bundu bzws workflow to stop in case of missing daily discharge values and other minor changes
author mschaefer
date Thu, 16 Aug 2018 08:47:41 +0200
parents 34cd4faf43f4
children 52314c4ab3be
comparison
equal deleted inserted replaced
9408:66a43d9f65c8 9409:38201f5b0dd9
23 import org.dive4elements.river.artifacts.resources.Resources; 23 import org.dive4elements.river.artifacts.resources.Resources;
24 import org.dive4elements.river.artifacts.services.AbstractMainValuesService.MainValuesServiceException; 24 import org.dive4elements.river.artifacts.services.AbstractMainValuesService.MainValuesServiceException;
25 import org.dive4elements.river.model.Gauge; 25 import org.dive4elements.river.model.Gauge;
26 import org.dive4elements.river.model.River; 26 import org.dive4elements.river.model.River;
27 import org.dive4elements.river.model.sinfo.DailyDischargeValue; 27 import org.dive4elements.river.model.sinfo.DailyDischargeValue;
28 import org.dive4elements.river.model.sinfo.DailyDischargeValue.MinMax;
29 import org.w3c.dom.Document; 28 import org.w3c.dom.Document;
30 import org.w3c.dom.Element; 29 import org.w3c.dom.Element;
31 import org.w3c.dom.NodeList; 30 import org.w3c.dom.NodeList;
32 31
33 /** 32 /**
34 * This service returns the main values of a river's gauge based on the start 33 * This service returns the list of gauges with daily discharge time periods and error messages
35 * and end point of the river.
36 *
37 * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
38 */ 34 */
39 public class DynamicMainValuesTimeRangeDeterminationService extends D4EService { 35 public class DynamicMainValuesTimeRangeDeterminationService extends D4EService {
40 36
41 private static final long serialVersionUID = 1L; 37 private static final long serialVersionUID = 1L;
42 38
51 public ServiceException(final String message) { 47 public ServiceException(final String message) {
52 super(message); 48 super(message);
53 } 49 }
54 } 50 }
55 51
56 /**
57 * Computes a gauge's main values for a period of time based on its daily discharges stored in the database
58 *
59 * @throws Exception
60 */
61
62 private static class GaugeInfoResult { 52 private static class GaugeInfoResult {
63 private final String globalErrorMsg; 53 protected final String globalErrorMsg;
64 private final List<GaugeInfo> gaugeInfos; 54 protected final List<GaugeInfo> gaugeInfos;
65 55
66 private GaugeInfoResult(final List<GaugeInfo> gaugeInfos, final String globalErrorMsg) { 56 protected GaugeInfoResult(final List<GaugeInfo> gaugeInfos, final String globalErrorMsg) {
67 this.gaugeInfos = gaugeInfos; 57 this.gaugeInfos = gaugeInfos;
68 this.globalErrorMsg = globalErrorMsg; 58 this.globalErrorMsg = globalErrorMsg;
69 } 59 }
70 60
71 private static class GaugeInfo { 61 private static class GaugeInfo {
72 private final String errorMsg; 62 protected final String errorMsg;
73 private final Gauge gauge; 63 protected final Gauge gauge;
74 private final Date startdate; 64 protected final Date startdate;
75 private final Date enddate; 65 protected final Date enddate;
76 66
77 public GaugeInfo(final String errorMsg, final Gauge gauge, final Date startdate, final Date enddate) { 67 public GaugeInfo(final String errorMsg, final Gauge gauge, final Date startdate, final Date enddate) {
78 this.errorMsg = errorMsg; 68 this.errorMsg = errorMsg;
79 this.gauge = gauge; 69 this.gauge = gauge;
80 this.startdate = startdate; 70 this.startdate = startdate;
81 this.enddate = enddate; 71 this.enddate = enddate;
82 } 72 }
83 } 73 }
84 } 74 }
85 75
76 /**
77 * Queries the available daily discharge time periods of a list of gauges from the database and checks the overlapping
78 *
79 * @throws ServiceException
80 */
86 private GaugeInfoResult getCommonTimeRangeForGauges(final List<Gauge> gauges, final Date startTime, final Date endTime, final CallMeta meta) 81 private GaugeInfoResult getCommonTimeRangeForGauges(final List<Gauge> gauges, final Date startTime, final Date endTime, final CallMeta meta)
87 throws ServiceException { 82 throws ServiceException {
88 83
89 // Query the gauge's daily Q values 84 // Query the gauge's daily Q values
85 String globalErrorMsg = "";
90 final List<GaugeInfoResult.GaugeInfo> gaugeResults = new ArrayList<>(); 86 final List<GaugeInfoResult.GaugeInfo> gaugeResults = new ArrayList<>();
91 Date min = startTime; 87 Date min = startTime;
92 Date max = endTime; 88 Date max = endTime;
93 89
94 for (final Gauge gauge : gauges) { 90 for (final Gauge gauge : gauges) {
95 91
96 final Date minGlobalForGauge = DailyDischargeValue.getGlobalMinMax(gauge, MinMax.min); 92 final Date[] gaugeDates = DailyDischargeValue.getTimePeriod(gauge, startTime, endTime);
97 final Date maxGlobalForGauge = DailyDischargeValue.getGlobalMinMax(gauge, MinMax.max); 93 if (gaugeDates[0] == null) {
98 if (minGlobalForGauge == null || maxGlobalForGauge == null) { // der Fall, dass nur eins von beiden null ist, kann eigentlich nciht vorkommen 94 final String msg = Resources.getMsg(meta, "bundu.wst_no_data_at_all", "bundu.wst_no_data_at_all", gauge.getName());
99 gaugeResults.add(new GaugeInfoResult.GaugeInfo(getMsg(meta, "bundu.wst_no_data_at_all"), gauge, null, null)); 95 final GaugeInfoResult.GaugeInfo gi = new GaugeInfoResult.GaugeInfo(msg, gauge, null, null);
100 // TODO : wenn der Workflow abgebrochen werden soll, GlobalErrorMsg setzen, dass mind. ein Pegel überhaupt keine Daten 96 gaugeResults.add(gi);
101 // hat (der Mechnismus auf Client-Seite ist schon implementiert) 97 if (globalErrorMsg.isEmpty())
102 98 globalErrorMsg = msg;
103 continue; 99 continue;
104 } 100 }
105 101
106 if (minGlobalForGauge.getTime() > startTime.getTime()) 102 if (gaugeDates[0].getTime() > startTime.getTime())
107 min = minGlobalForGauge; 103 min = gaugeDates[0];
108 104
109 if (maxGlobalForGauge.getTime() < endTime.getTime()) 105 if (gaugeDates[1].getTime() < endTime.getTime())
110 max = maxGlobalForGauge; 106 max = gaugeDates[1];
111 107
112 String errormsg = null; 108 String errormsg = null;
113 if ((maxGlobalForGauge.getTime() < endTime.getTime()) || (minGlobalForGauge.getTime() > startTime.getTime())) 109 if ((gaugeDates[1].getTime() < endTime.getTime()) || (gaugeDates[0].getTime() > startTime.getTime()))
114 errormsg = makeDoesNotCoverErrorMsg(minGlobalForGauge, maxGlobalForGauge, meta); 110 errormsg = makeDoesNotCoverErrorMsg(gaugeDates[0], gaugeDates[1], meta);
115 111
116 gaugeResults.add(new GaugeInfoResult.GaugeInfo(errormsg, gauge, min, max)); 112 gaugeResults.add(new GaugeInfoResult.GaugeInfo(errormsg, gauge, min, max));
117 } 113 }
118 114
119 // common Range and correct errorMsg 115 // common Range and correct errorMsg
120 final List<GaugeInfoResult.GaugeInfo> gaugeResultsSecondTurn = new ArrayList<>(); 116 final List<GaugeInfoResult.GaugeInfo> gaugeResultsSecondTurn = new ArrayList<>();
121 for (final GaugeInfoResult.GaugeInfo gi : gaugeResults) { 117 for (final GaugeInfoResult.GaugeInfo gi : gaugeResults) {
122 gaugeResultsSecondTurn 118 gaugeResultsSecondTurn.add(new GaugeInfoResult.GaugeInfo(gi.errorMsg, gi.gauge, gi.startdate != null ? min : null,
123 .add(new GaugeInfoResult.GaugeInfo(gi.errorMsg, gi.gauge, gi.startdate != null ? min : null, gi.enddate != null ? max : null)); 119 gi.enddate != null ? max : null));
124 } 120 }
125 final String globalErrorMsg = (min.getTime() > max.getTime()) ? getMsg(meta, "bundu.wst.gauge_timeranges_disjoint") : ""; 121 if (globalErrorMsg.isEmpty() && (min.getTime() > max.getTime()))
122 globalErrorMsg = getMsg(meta, "bundu.wst.gauge_timeranges_disjoint");
126 final GaugeInfoResult result = new GaugeInfoResult(gaugeResultsSecondTurn, globalErrorMsg); 123 final GaugeInfoResult result = new GaugeInfoResult(gaugeResultsSecondTurn, globalErrorMsg);
127 124
128 return result; 125 return result;
129 } 126 }
130 127
138 } 135 }
139 136
140 @Override 137 @Override
141 public Document doProcess(final Document data, final GlobalContext context, final CallMeta callMeta) { 138 public Document doProcess(final Document data, final GlobalContext context, final CallMeta callMeta) {
142 try { 139 try {
143 final River river = AbstractMainValuesService.getRequestedRiver(data, "/art:" + this.ROOT_NODE + "/art:river/text()"); 140 final River river = AbstractMainValuesService.getRequestedRiver(data, "/art:" + ROOT_NODE + "/art:river/text()");
144 final List<Gauge> gauges = getRequestedGauges(data, river, callMeta); 141 final List<Gauge> gauges = getRequestedGauges(data, river, callMeta);
145 final Date start = getRequestedStartYear(data, "/art:" + this.ROOT_NODE + "/art:startYear/text()"); 142 final Date start = getRequestedStartYear(data, "/art:" + ROOT_NODE + "/art:startYear/text()");
146 final Date end = getRequestedEndYear(data, "/art:" + this.ROOT_NODE + "/art:endYear/text()"); 143 final Date end = getRequestedEndYear(data, "/art:" + ROOT_NODE + "/art:endYear/text()");
147 144
148 final GaugeInfoResult result = getCommonTimeRangeForGauges(gauges, start, end, callMeta); 145 final GaugeInfoResult result = getCommonTimeRangeForGauges(gauges, start, end, callMeta);
149 146
150 return buildDocument(result, context, callMeta); 147 return buildDocument(result, context, callMeta);
151 } 148 }

http://dive4elements.wald.intevation.org