Mercurial > dive4elements > river
view flys-artifacts/src/main/java/de/intevation/flys/artifacts/services/MainValuesService.java @ 4031:e4e345d81a65
issue889/2
author | Felix Wolfsteller <felix.wolfsteller@intevation.de> |
---|---|
date | Thu, 04 Oct 2012 14:54:44 +0200 |
parents | 0c217de0d84b |
children |
line wrap: on
line source
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.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() { } private static final Document error(String msg) { logger.debug(msg); return XMLUtils.newDocument(); } @Override public Document doProcess( Document data, GlobalContext context, CallMeta callMeta ) { logger.debug("MainValuesService.process"); River river = getRequestedRiver(data); if (river == null) { return error("no river found."); } double[] minmax = getRequestedStartEnd(data, river); Gauge gauge = river.determineGauge(minmax[0], minmax[1]); if (gauge == null) { return error("no gauge found."); } List<MainValue> mainValues = getMainValues(river, gauge); return buildDocument(river, gauge, mainValues, context); } /** * 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); return riverStr != null && (riverStr = riverStr.trim()).length() > 0 ? RiverFactory.getRiver(riverStr) : null; } /** * 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); if (startStr == null || endStr == null) { return river.determineMinMaxDistance(); } try { double start = Double.parseDouble(startStr); double end = Double.parseDouble(endStr); if (logger.isDebugEnabled()) { 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) { if (logger.isDebugEnabled()) { logger.debug("MainValuesService.buildMainValues"); logger.debug("River: " + river.getName()); logger.debug("Gauge: " + gauge.getName()); } List<MainValue> mainValues = gauge.getMainValues(); if (logger.isDebugEnabled()) { 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 :