comparison flys-artifacts/src/main/java/de/intevation/flys/artifacts/services/MainValuesService.java @ 3318:dbe2f85bf160

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

http://dive4elements.wald.intevation.org