comparison flys-artifacts/src/main/java/de/intevation/flys/artifacts/services/MainValuesService.java @ 331:5a2df8677b3e

Added a service that returns the MainValues of a Gauge based on a river name and a stationing. flys-artifacts/trunk@1729 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Ingo Weinzierl <ingo.weinzierl@intevation.de>
date Tue, 19 Apr 2011 12:33:39 +0000
parents
children 932a5e3c7fa1
comparison
equal deleted inserted replaced
330:4791fd92a208 331:5a2df8677b3e
1 package de.intevation.flys.artifacts.services;
2
3 import java.util.List;
4
5 import org.apache.log4j.Logger;
6
7 import org.w3c.dom.Document;
8 import org.w3c.dom.Element;
9
10 import org.hibernate.Session;
11
12 import de.intevation.artifacts.CallMeta;
13
14 import de.intevation.artifactdatabase.DefaultService;
15
16 import de.intevation.artifacts.common.ArtifactNamespaceContext;
17 import de.intevation.artifacts.common.utils.XMLUtils;
18 import de.intevation.artifacts.common.utils.XMLUtils.ElementCreator;
19
20 import de.intevation.flys.backend.SessionHolder;
21 import de.intevation.flys.model.Gauge;
22 import de.intevation.flys.model.MainValue;
23 import de.intevation.flys.model.MainValueType;
24 import de.intevation.flys.model.NamedMainValue;
25 import de.intevation.flys.model.Range;
26 import de.intevation.flys.model.River;
27
28 import de.intevation.flys.artifacts.model.MainValuesFactory;
29 import de.intevation.flys.artifacts.model.RiverFactory;
30
31
32 /**
33 * This service returns the main values of a river's gauge based on the start
34 * and end point of the river.
35 *
36 * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
37 */
38 public class MainValuesService extends DefaultService {
39
40 /** The logger that is used by this service.*/
41 private static Logger logger = Logger.getLogger(MainValuesService.class);
42
43
44 /** The XPath that points to the river definition of the incoming request.*/
45 public static final String XPATH_RIVER = "/art:mainvalues/art:river/text()";
46
47 /** The XPath that points to the start definition of the incoming request.*/
48 public static final String XPATH_START = "/art:mainvalues/art:end/text()";
49
50 /** The XPath that points to the end definition of the incoming request.*/
51 public static final String XPATH_END = "/art:mainvalues/art:start/text()";
52
53 /**
54 * The default constructor.
55 */
56 public MainValuesService() {
57 }
58
59
60 public Document process(
61 Document data,
62 Object context,
63 CallMeta callMeta)
64 {
65 logger.debug("MainValuesService.process");
66
67 try {
68 River river = getRequestedRiver(data);
69 double[] minmax = getRequestedStartEnd(data, river);
70 Gauge gauge = river.determineGauge(minmax[0], minmax[1]);
71
72 List<MainValue> mainValues = getMainValues(river, gauge);
73
74 return buildDocument(river, gauge, mainValues, context);
75 }
76 catch (NullPointerException npe) {
77 logger.error("Could not process the request.");
78 logger.error(npe, npe);
79
80 return XMLUtils.newDocument();
81 }
82 }
83
84
85 /**
86 * This method extracts the river from the incoming request. If no river
87 * string was found or no river is found in the database based on this
88 * string a NullPointerException is thrown.
89 *
90 * @param data The incoming request data.
91 *
92 * @return the River object.
93 */
94 protected River getRequestedRiver(Document data)
95 throws NullPointerException
96 {
97 logger.debug("MainValuesService.getRiver");
98
99 String riverStr = XMLUtils.xpathString(
100 data, XPATH_RIVER, ArtifactNamespaceContext.INSTANCE);
101
102 if (riverStr == null || riverStr.trim().length() == 0) {
103 throw new NullPointerException("No river found in the request.");
104 }
105
106 River river = RiverFactory.getRiver(riverStr);
107
108 if (river == null) {
109 throw new NullPointerException("No such river found: " + riverStr);
110 }
111
112 return river;
113 }
114
115
116 /**
117 * This method extracts the start and end point from incoming request
118 * document and returns both values in an array. If no start and end strings
119 * are found in the document, the min/max values of the <i>river</i> are
120 * returned.
121 *
122 * @param data The incoming request data.
123 * @param river The river of the request.
124 *
125 * @return the start and end point.
126 */
127 protected double[] getRequestedStartEnd(Document data, River river) {
128 logger.debug("MainValuesService.getStartEnd");
129
130 String startStr = XMLUtils.xpathString(
131 data, XPATH_START, ArtifactNamespaceContext.INSTANCE);
132
133 String endStr = XMLUtils.xpathString(
134 data, XPATH_END, ArtifactNamespaceContext.INSTANCE);
135
136 try {
137 double start = Double.parseDouble(startStr);
138 double end = Double.parseDouble(endStr);
139
140 logger.debug("Found start: " + start);
141 logger.debug("Found end: " + end);
142
143 return new double[] { start, end };
144 }
145 catch (NumberFormatException nfe) {
146 logger.warn(nfe, nfe);
147
148 return river.determineMinMaxDistance();
149 }
150 }
151
152
153 /**
154 * This method creates the result document that includes the main values of
155 * the specified <i>gauge</i>.
156 *
157 * @param river The river.
158 * @param gauge The gauge.
159 *
160 * @return a document that includes the main values of the specified river
161 * at the specified gauge.
162 */
163 protected List<MainValue> getMainValues(River river, Gauge gauge)
164 throws NullPointerException
165 {
166 if (logger.isDebugEnabled()) {
167 logger.debug("MainValuesService.buildMainValues");
168 logger.debug("River: " + river.getName());
169 logger.debug("Gauge: " + gauge.getName());
170 }
171
172 Session session = SessionHolder.acquire();
173 try {
174 List<MainValue> mainValues = MainValuesFactory.getMainValues(gauge);
175
176 if (mainValues == null || mainValues.isEmpty()) {
177 throw new NullPointerException("No main values found.");
178 }
179
180 logger.debug(mainValues.size() + " main values found.");
181
182 return mainValues;
183 }
184 finally {
185 session.close();
186 SessionHolder.release();
187 }
188 }
189
190
191 protected Document buildDocument(
192 River river,
193 Gauge gauge,
194 List<MainValue> mainValues,
195 Object context)
196 {
197 logger.debug("MainValuesService.buildDocument");
198
199 Document doc = XMLUtils.newDocument();
200
201 ElementCreator cr = new ElementCreator(
202 doc,
203 ArtifactNamespaceContext.NAMESPACE_URI,
204 ArtifactNamespaceContext.NAMESPACE_PREFIX);
205
206 Element rootEl = cr.create("service");
207 cr.addAttr(rootEl, "name", "mainvalues");
208
209 doc.appendChild(rootEl);
210
211 appendMetaInformation(doc, rootEl, river, gauge, context);
212 appendMainValues(doc, rootEl, mainValues, context);
213
214 return doc;
215 }
216
217
218 /**
219 * This method appends some meta information to the result document.
220 * Currently, the river's and gauge's names and the gauge's range are
221 * appended.
222 *
223 * @param root The root element of the result document.
224 * @param river The river.
225 * @param gauge The gauge.
226 * @param context The context object.
227 */
228 protected void appendMetaInformation(
229 Document doc,
230 Element root,
231 River river,
232 Gauge gauge,
233 Object context)
234 {
235 logger.debug("MainValuesService.appendMetaInformation");
236
237 ElementCreator cr = new ElementCreator(
238 doc,
239 ArtifactNamespaceContext.NAMESPACE_URI,
240 ArtifactNamespaceContext.NAMESPACE_PREFIX);
241
242 Range range = gauge.getRange();
243
244 Element riverEl = cr.create("river");
245 cr.addAttr(riverEl, "name", river.getName());
246
247 Element gaugeEl = cr.create("gauge");
248 cr.addAttr(gaugeEl, "name", gauge.getName());
249 cr.addAttr(gaugeEl, "from", range.getA().toString());
250 cr.addAttr(gaugeEl, "to", range.getB().toString());
251
252 root.appendChild(riverEl);
253 root.appendChild(gaugeEl);
254 }
255
256
257 protected void appendMainValues(
258 Document doc,
259 Element root,
260 List<MainValue> mainValues,
261 Object context)
262 {
263 logger.debug("MainValuesService.appendMainValues");
264
265 ElementCreator cr = new ElementCreator(
266 doc,
267 ArtifactNamespaceContext.NAMESPACE_URI,
268 ArtifactNamespaceContext.NAMESPACE_PREFIX);
269
270 Element list = cr.create("mainvalues");
271
272 for (MainValue mainValue: mainValues) {
273 Element newEl = buildMainValueElement(doc, mainValue, context);
274
275 if (newEl != null) {
276 list.appendChild(newEl);
277 }
278 }
279
280 root.appendChild(list);
281 }
282
283
284 /**
285 * This method builds a concrete mainvalue element. This element consists of
286 * three attributes: the value, its name and its type.
287 *
288 * @param doc The owner document.
289 * @param mainValue The mainvalue.
290 * @param context The context object.
291 *
292 * @return a mainvalue element.
293 */
294 protected Element buildMainValueElement(
295 Document doc,
296 MainValue mainValue,
297 Object context)
298 {
299 ElementCreator cr = new ElementCreator(
300 doc,
301 ArtifactNamespaceContext.NAMESPACE_URI,
302 ArtifactNamespaceContext.NAMESPACE_PREFIX);
303
304 NamedMainValue namedMainValue = mainValue.getMainValue();
305 MainValueType mainValueType = namedMainValue.getType();
306
307 Element el = cr.create("mainvalue");
308
309 cr.addAttr(el, "value", mainValue.getValue().toString());
310 cr.addAttr(el, "name", namedMainValue.getName());
311 cr.addAttr(el, "type", mainValueType.getName());
312
313 return el;
314 }
315 }
316 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org