Mercurial > dive4elements > river
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/services/MainValuesService.java Fri Sep 28 12:14:35 2012 +0200 @@ -0,0 +1,308 @@ +package de.intevation.flys.artifacts.services; + +import java.util.List; + +import org.apache.log4j.Logger; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import de.intevation.artifacts.CallMeta; +import de.intevation.artifacts.GlobalContext; + +import de.intevation.artifacts.common.ArtifactNamespaceContext; +import de.intevation.artifacts.common.utils.XMLUtils; +import de.intevation.artifacts.common.utils.XMLUtils.ElementCreator; + +import de.intevation.flys.model.Gauge; +import de.intevation.flys.model.MainValue; +import de.intevation.flys.model.MainValueType; +import de.intevation.flys.model.NamedMainValue; +import de.intevation.flys.model.Range; +import de.intevation.flys.model.River; + +import de.intevation.flys.artifacts.model.MainValuesFactory; +import de.intevation.flys.artifacts.model.RiverFactory; + + +/** + * This service returns the main values of a river's gauge based on the start + * and end point of the river. + * + * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a> + */ +public class MainValuesService extends FLYSService { + + /** The logger that is used by this service.*/ + private static Logger logger = Logger.getLogger(MainValuesService.class); + + + /** The XPath that points to the river definition of the incoming request.*/ + public static final String XPATH_RIVER = "/art:mainvalues/art:river/text()"; + + /** The XPath that points to the start definition of the incoming request.*/ + public static final String XPATH_START = "/art:mainvalues/art:start/text()"; + + /** The XPath that points to the end definition of the incoming request.*/ + public static final String XPATH_END = "/art:mainvalues/art:end/text()"; + + /** + * The default constructor. + */ + public MainValuesService() { + } + + + @Override + public Document doProcess( + Document data, + GlobalContext context, + CallMeta callMeta + ) { + logger.debug("MainValuesService.process"); + + try { + River river = getRequestedRiver(data); + double[] minmax = getRequestedStartEnd(data, river); + Gauge gauge = river.determineGauge(minmax[0], minmax[1]); + + logger.debug("Found gauge: " + gauge.getName()); + + List<MainValue> mainValues = getMainValues(river, gauge); + + return buildDocument(river, gauge, mainValues, context); + } + catch (NullPointerException npe) { + logger.error("Could not process the request."); + logger.error(npe, npe); + + return XMLUtils.newDocument(); + } + } + + + /** + * This method extracts the river from the incoming request. If no river + * string was found or no river is found in the database based on this + * string a NullPointerException is thrown. + * + * @param data The incoming request data. + * + * @return the River object. + */ + protected River getRequestedRiver(Document data) + throws NullPointerException + { + logger.debug("MainValuesService.getRiver"); + + String riverStr = XMLUtils.xpathString( + data, XPATH_RIVER, ArtifactNamespaceContext.INSTANCE); + + if (riverStr == null || riverStr.trim().length() == 0) { + throw new NullPointerException("No river found in the request."); + } + + River river = RiverFactory.getRiver(riverStr); + + if (river == null) { + throw new NullPointerException("No such river found: " + riverStr); + } + + return river; + } + + + /** + * This method extracts the start and end point from incoming request + * document and returns both values in an array. If no start and end strings + * are found in the document, the min/max values of the <i>river</i> are + * returned. + * + * @param data The incoming request data. + * @param river The river of the request. + * + * @return the start and end point. + */ + protected double[] getRequestedStartEnd(Document data, River river) { + logger.debug("MainValuesService.getStartEnd"); + + String startStr = XMLUtils.xpathString( + data, XPATH_START, ArtifactNamespaceContext.INSTANCE); + + String endStr = XMLUtils.xpathString( + data, XPATH_END, ArtifactNamespaceContext.INSTANCE); + + try { + double start = Double.parseDouble(startStr); + double end = Double.parseDouble(endStr); + + logger.debug("Found start: " + start); + logger.debug("Found end: " + end); + + return new double[] { start, end }; + } + catch (NumberFormatException nfe) { + logger.warn(nfe, nfe); + + return river.determineMinMaxDistance(); + } + } + + + /** + * This method creates the result document that includes the main values of + * the specified <i>gauge</i>. + * + * @param river The river. + * @param gauge The gauge. + * + * @return a document that includes the main values of the specified river + * at the specified gauge. + */ + protected List<MainValue> getMainValues(River river, Gauge gauge) + throws NullPointerException + { + if (logger.isDebugEnabled()) { + logger.debug("MainValuesService.buildMainValues"); + logger.debug("River: " + river.getName()); + logger.debug("Gauge: " + gauge.getName()); + } + + List<MainValue> mainValues = MainValuesFactory.getMainValues(gauge); + + if (mainValues == null || mainValues.isEmpty()) { + throw new NullPointerException("No main values found."); + } + + logger.debug(mainValues.size() + " main values found."); + + return mainValues; + } + + + protected Document buildDocument( + River river, + Gauge gauge, + List<MainValue> mainValues, + Object context) + { + logger.debug("MainValuesService.buildDocument"); + + Document doc = XMLUtils.newDocument(); + + ElementCreator cr = new ElementCreator( + doc, + ArtifactNamespaceContext.NAMESPACE_URI, + ArtifactNamespaceContext.NAMESPACE_PREFIX); + + Element rootEl = cr.create("service"); + cr.addAttr(rootEl, "name", "mainvalues"); + + doc.appendChild(rootEl); + + appendMetaInformation(doc, rootEl, river, gauge, context); + appendMainValues(doc, rootEl, mainValues, context); + + return doc; + } + + + /** + * This method appends some meta information to the result document. + * Currently, the river's and gauge's names and the gauge's range are + * appended. + * + * @param root The root element of the result document. + * @param river The river. + * @param gauge The gauge. + * @param context The context object. + */ + protected void appendMetaInformation( + Document doc, + Element root, + River river, + Gauge gauge, + Object context) + { + logger.debug("MainValuesService.appendMetaInformation"); + + ElementCreator cr = new ElementCreator( + doc, + ArtifactNamespaceContext.NAMESPACE_URI, + ArtifactNamespaceContext.NAMESPACE_PREFIX); + + Range range = gauge.getRange(); + + Element riverEl = cr.create("river"); + cr.addAttr(riverEl, "name", river.getName()); + + Element gaugeEl = cr.create("gauge"); + cr.addAttr(gaugeEl, "name", gauge.getName()); + cr.addAttr(gaugeEl, "from", range.getA().toString()); + cr.addAttr(gaugeEl, "to", range.getB().toString()); + + root.appendChild(riverEl); + root.appendChild(gaugeEl); + } + + + protected void appendMainValues( + Document doc, + Element root, + List<MainValue> mainValues, + Object context) + { + logger.debug("MainValuesService.appendMainValues"); + + ElementCreator cr = new ElementCreator( + doc, + ArtifactNamespaceContext.NAMESPACE_URI, + ArtifactNamespaceContext.NAMESPACE_PREFIX); + + Element list = cr.create("mainvalues"); + + for (MainValue mainValue: mainValues) { + Element newEl = buildMainValueElement(doc, mainValue, context); + + if (newEl != null) { + list.appendChild(newEl); + } + } + + root.appendChild(list); + } + + + /** + * This method builds a concrete mainvalue element. This element consists of + * three attributes: the value, its name and its type. + * + * @param doc The owner document. + * @param mainValue The mainvalue. + * @param context The context object. + * + * @return a mainvalue element. + */ + protected Element buildMainValueElement( + Document doc, + MainValue mainValue, + Object context) + { + ElementCreator cr = new ElementCreator( + doc, + ArtifactNamespaceContext.NAMESPACE_URI, + ArtifactNamespaceContext.NAMESPACE_PREFIX); + + NamedMainValue namedMainValue = mainValue.getMainValue(); + MainValueType mainValueType = namedMainValue.getType(); + + Element el = cr.create("mainvalue"); + + cr.addAttr(el, "value", mainValue.getValue().toString()); + cr.addAttr(el, "name", namedMainValue.getName()); + cr.addAttr(el, "type", mainValueType.getName()); + + return el; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :