comparison flys-artifacts/src/main/java/de/intevation/flys/artifacts/services/MainValuesService.java @ 1190:f514894ec2fd

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

http://dive4elements.wald.intevation.org