Mercurial > dive4elements > river
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 : |