comparison artifacts/src/main/java/org/dive4elements/river/artifacts/services/MainValuesService.java @ 9288:82c67b859aa7

bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
author gernotbelger
date Tue, 24 Jul 2018 10:39:03 +0200
parents 5e38e2924c07
children bc9a45d2b1fa
comparison
equal deleted inserted replaced
9287:6c88ad449c83 9288:82c67b859aa7
9 package org.dive4elements.river.artifacts.services; 9 package org.dive4elements.river.artifacts.services;
10 10
11 import java.util.List; 11 import java.util.List;
12 12
13 import org.apache.log4j.Logger; 13 import org.apache.log4j.Logger;
14
15 import org.w3c.dom.Document;
16 import org.w3c.dom.Element;
17
18 import org.dive4elements.artifacts.CallMeta; 14 import org.dive4elements.artifacts.CallMeta;
19 import org.dive4elements.artifacts.GlobalContext; 15 import org.dive4elements.artifacts.GlobalContext;
20
21 import org.dive4elements.artifacts.common.ArtifactNamespaceContext;
22 import org.dive4elements.artifacts.common.utils.XMLUtils;
23 import org.dive4elements.artifacts.common.utils.XMLUtils.ElementCreator;
24
25 import org.dive4elements.river.model.Gauge; 16 import org.dive4elements.river.model.Gauge;
26 import org.dive4elements.river.model.MainValue; 17 import org.dive4elements.river.model.MainValue;
27 import org.dive4elements.river.model.MainValueType;
28 import org.dive4elements.river.model.NamedMainValue;
29 import org.dive4elements.river.model.OfficialLine;
30 import org.dive4elements.river.model.Range;
31 import org.dive4elements.river.model.River; 18 import org.dive4elements.river.model.River;
32 19 import org.w3c.dom.Document;
33 import org.dive4elements.river.artifacts.model.RiverFactory;
34
35 import static org.dive4elements.river.backend.utils.EpsilonComparator.CMP;
36
37 20
38 /** 21 /**
39 * This service returns the main values of a river's gauge based on the start 22 * This service returns the main values of a river's gauge based on the start
40 * and end point of the river. 23 * and end point of the river.
41 * 24 *
42 * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a> 25 * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
43 */ 26 */
44 public class MainValuesService extends D4EService { 27 public class MainValuesService extends AbstractMainValuesService {
45 28
46 /** The log that is used by this service.*/ 29 private static final long serialVersionUID = 1L;
30
31 /** The log that is used by this service. */
47 private static Logger log = Logger.getLogger(MainValuesService.class); 32 private static Logger log = Logger.getLogger(MainValuesService.class);
48 33
49 /** XPath that points to the river definition of the incoming request.*/ 34 @Override
50 public static final String XPATH_RIVER = 35 public Document doProcess(final Document data, final GlobalContext context, final CallMeta callMeta) {
51 "/art:mainvalues/art:river/text()"; 36 try {
37 final River river = getRequestedRiver(data);
38 final Gauge gauge = getRequestedGauge(data, river);
52 39
53 /** XPath that points to the start definition of the incoming request.*/ 40 final List<MainValue> mainValues = getMainValues(river, gauge);
54 public static final String XPATH_START =
55 "/art:mainvalues/art:start/text()";
56 41
57 /** The XPath that points to the end definition of the incoming request.*/ 42 return buildDocument(river, gauge, mainValues, context);
58 public static final String XPATH_END = "/art:mainvalues/art:end/text()";
59
60 protected CallMeta callMeta;
61
62
63 /**
64 * The default constructor.
65 */
66 public MainValuesService() {
67 }
68
69 private static final Document error(String msg) {
70 log.debug(msg);
71 return XMLUtils.newDocument();
72 }
73
74
75 @Override
76 public Document doProcess(
77 Document data,
78 GlobalContext context,
79 CallMeta callMeta
80 ) {
81 log.debug("MainValuesService.process");
82
83 this.callMeta = callMeta;
84
85 River river = getRequestedRiver(data);
86 if (river == null) {
87 return error("no river found.");
88 } 43 }
89 44 catch (final MainValuesServiceException e) {
90 double[] minmax = getRequestedStartEnd(data, river); 45 e.printStackTrace();
91 Gauge gauge = river.determineRefGauge(minmax, 46 return error(e.getMessage());
92 CMP.compare(minmax[0], minmax[1]) != 0);
93
94 if (gauge == null) {
95 return error("no gauge found.");
96 }
97
98 List<MainValue> mainValues = getMainValues(river, gauge);
99
100 return buildDocument(river, gauge, mainValues, context);
101 }
102
103
104 /**
105 * This method extracts the river from the incoming request. If no river
106 * string was found or no river is found in the database based on this
107 * string a NullPointerException is thrown.
108 *
109 * @param data The incoming request data.
110 *
111 * @return the River object.
112 */
113 protected River getRequestedRiver(Document data)
114 throws NullPointerException
115 {
116 log.debug("MainValuesService.getRequestedRiver");
117
118 String riverStr = XMLUtils.xpathString(
119 data, XPATH_RIVER, ArtifactNamespaceContext.INSTANCE);
120
121 return riverStr != null && (riverStr = riverStr.trim()).length() > 0
122 ? RiverFactory.getRiver(riverStr)
123 : null;
124 }
125
126
127 /**
128 * This method extracts the start and end point from incoming request
129 * document and returns both values in an array.
130 * If no start and end strings
131 * are found in the document, the min/max values of the <i>river</i> are
132 * returned.
133 *
134 * @param data The incoming request data.
135 * @param river The river of the request.
136 *
137 * @return the start and end point.
138 */
139 protected double[] getRequestedStartEnd(Document data, River river) {
140 log.debug("MainValuesService.getStartEnd");
141
142 String startStr = XMLUtils.xpathString(
143 data, XPATH_START, ArtifactNamespaceContext.INSTANCE);
144
145 String endStr = XMLUtils.xpathString(
146 data, XPATH_END, ArtifactNamespaceContext.INSTANCE);
147
148 if (startStr == null || endStr == null) {
149 return river.determineMinMaxDistance();
150 }
151
152 try {
153 double start = Double.parseDouble(startStr);
154 double end = Double.parseDouble(endStr);
155
156 if (log.isDebugEnabled()) {
157 log.debug("Found start: " + start);
158 log.debug("Found end: " + end);
159 }
160
161 return new double[] { start, end };
162 }
163 catch (NumberFormatException nfe) {
164 log.warn(nfe, nfe);
165 return river.determineMinMaxDistance();
166 } 47 }
167 } 48 }
168
169 49
170 /** 50 /**
171 * This method creates the result document that includes the main values of 51 * This method creates the result document that includes the main values of
172 * the specified <i>gauge</i>. 52 * the specified <i>gauge</i>.
173 * 53 *
174 * @param river The river. 54 * @param river
175 * @param gauge The gauge. 55 * The river.
56 * @param gauge
57 * The gauge.
176 * 58 *
177 * @return a document that includes the main values of the specified river 59 * @return a document that includes the main values of the specified river
178 * at the specified gauge. 60 * at the specified gauge.
179 */ 61 */
180 protected List<MainValue> getMainValues(River river, Gauge gauge) { 62 protected List<MainValue> getMainValues(final River river, final Gauge gauge) {
181 63
182 if (log.isDebugEnabled()) { 64 if (log.isDebugEnabled()) {
183 log.debug("MainValuesService.buildMainValues"); 65 log.debug("MainValuesService.buildMainValues");
184 log.debug("River: " + river.getName()); 66 log.debug("River: " + river.getName());
185 log.debug("Gauge: " + gauge.getName()); 67 log.debug("Gauge: " + gauge.getName());
186 } 68 }
187 69
188 List<MainValue> mainValues = gauge.getMainValues(); 70 final List<MainValue> mainValues = gauge.getMainValues();
189 71
190 if (log.isDebugEnabled()) { 72 if (log.isDebugEnabled()) {
191 log.debug(mainValues.size() + " main values found."); 73 log.debug(mainValues.size() + " main values found.");
192 } 74 }
193 75
194 return mainValues; 76 return mainValues;
195 } 77 }
196
197
198 protected Document buildDocument(
199 River river,
200 Gauge gauge,
201 List<MainValue> mainValues,
202 Object context)
203 {
204 log.debug("MainValuesService.buildDocument");
205
206 Document doc = XMLUtils.newDocument();
207
208 ElementCreator cr = new ElementCreator(
209 doc,
210 ArtifactNamespaceContext.NAMESPACE_URI,
211 ArtifactNamespaceContext.NAMESPACE_PREFIX);
212
213 Element rootEl = cr.create("service");
214 cr.addAttr(rootEl, "name", "mainvalues");
215
216 doc.appendChild(rootEl);
217
218 appendMetaInformation(doc, rootEl, river, gauge, context);
219 appendMainValues(doc, rootEl, mainValues, river.getId(), context);
220
221 return doc;
222 }
223
224
225 /**
226 * This method appends some meta information to the result document.
227 * Currently, the river's and gauge's names and the gauge's range are
228 * appended.
229 *
230 * @param root The root element of the result document.
231 * @param river The river.
232 * @param gauge The gauge.
233 * @param context The context object.
234 */
235 protected void appendMetaInformation(
236 Document doc,
237 Element root,
238 River river,
239 Gauge gauge,
240 Object context)
241 {
242 log.debug("MainValuesService.appendMetaInformation");
243
244 ElementCreator cr = new ElementCreator(
245 doc,
246 ArtifactNamespaceContext.NAMESPACE_URI,
247 ArtifactNamespaceContext.NAMESPACE_PREFIX);
248
249 Range range = gauge.getRange();
250
251 Element riverEl = cr.create("river");
252 cr.addAttr(riverEl, "name", river.getName());
253
254 Element gaugeEl = cr.create("gauge");
255 cr.addAttr(gaugeEl, "name", gauge.getName());
256 cr.addAttr(gaugeEl, "from", range.getA().toString());
257 cr.addAttr(gaugeEl, "to", range.getB().toString());
258
259 root.appendChild(riverEl);
260 root.appendChild(gaugeEl);
261 }
262
263
264 /** Checks i a main value has an official associated, */
265 protected static boolean hasOfficialLine(
266 NamedMainValue nmv,
267 Integer riverId
268 ) {
269 for (OfficialLine ol: nmv.getOfficialLines()) {
270 if (
271 ol.getWstColumn().getWst().getRiver().getId().equals(riverId)
272 ) {
273 return true;
274 }
275 }
276 return false;
277 }
278
279
280 /** Append xml representation of main values to document. */
281 protected void appendMainValues(
282 Document doc,
283 Element root,
284 List<MainValue> mainValues,
285 Integer riverId,
286 Object context)
287 {
288 log.debug("MainValuesService.appendMainValues");
289
290 ElementCreator cr = new ElementCreator(
291 doc,
292 ArtifactNamespaceContext.NAMESPACE_URI,
293 ArtifactNamespaceContext.NAMESPACE_PREFIX);
294
295 Element list = cr.create("mainvalues");
296
297 for (MainValue mainValue: mainValues) {
298 Element newEl = buildMainValueElement(
299 doc, mainValue, riverId, context);
300
301 if (newEl != null) {
302 list.appendChild(newEl);
303 }
304 }
305
306 root.appendChild(list);
307 }
308
309
310 /**
311 * This method builds a concrete mainvalue element. This element consists of
312 * three attributes: the value, its name and its type.
313 *
314 * @param doc The owner document.
315 * @param mainValue The mainvalue.
316 * @param context The context object.
317 *
318 * @return a mainvalue element.
319 */
320 protected Element buildMainValueElement(
321 Document doc,
322 MainValue mainValue,
323 Integer riverId,
324 Object context)
325 {
326 ElementCreator cr = new ElementCreator(
327 doc,
328 ArtifactNamespaceContext.NAMESPACE_URI,
329 ArtifactNamespaceContext.NAMESPACE_PREFIX);
330
331 NamedMainValue namedMainValue = mainValue.getMainValue();
332 MainValueType mainValueType = namedMainValue.getType();
333
334 Element el = cr.create("mainvalue");
335
336 cr.addAttr(el, "value", mainValue.getValue().toString());
337 cr.addAttr(el, "name", namedMainValue.getName());
338 cr.addAttr(el, "type", mainValueType.getName());
339 if (mainValue.getTimeInterval() != null) {
340 if (mainValue.getTimeInterval().getStartTime() != null) {
341 cr.addAttr(el, "starttime",
342 Long.toString(
343 mainValue.getTimeInterval().getStartTime().getTime()));
344 }
345 if (mainValue.getTimeInterval().getStopTime() != null) {
346 cr.addAttr(el, "stoptime",
347 Long.toString(
348 mainValue.getTimeInterval().getStopTime().getTime()));
349 }
350 }
351
352 if (hasOfficialLine(namedMainValue, riverId)) {
353 cr.addAttr(el, "official", "true");
354 }
355
356 return el;
357 }
358 } 78 }
359 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org