Mercurial > dive4elements > river
view artifacts/src/main/java/org/dive4elements/river/artifacts/services/AbstractMainValuesService.java @ 9404:bc9a45d2b1fa
common time range for gauges incl. error messages
author | gernotbelger |
---|---|
date | Wed, 15 Aug 2018 13:59:09 +0200 |
parents | 82c67b859aa7 |
children |
line wrap: on
line source
/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde * Software engineering by Intevation GmbH * * This file is Free Software under the GNU AGPL (>=v3) * and comes with ABSOLUTELY NO WARRANTY! Check out the * documentation coming with Dive4Elements River for details. */ package org.dive4elements.river.artifacts.services; import static org.dive4elements.river.backend.utils.EpsilonComparator.CMP; import java.util.List; import org.apache.log4j.Logger; import org.dive4elements.artifacts.common.ArtifactNamespaceContext; import org.dive4elements.artifacts.common.utils.XMLUtils; import org.dive4elements.artifacts.common.utils.XMLUtils.ElementCreator; import org.dive4elements.river.artifacts.model.RiverFactory; import org.dive4elements.river.model.Gauge; import org.dive4elements.river.model.MainValue; import org.dive4elements.river.model.MainValueType; import org.dive4elements.river.model.NamedMainValue; import org.dive4elements.river.model.OfficialLine; import org.dive4elements.river.model.Range; import org.dive4elements.river.model.River; import org.w3c.dom.Document; import org.w3c.dom.Element; /** * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a> */ abstract class AbstractMainValuesService extends D4EService { private static final long serialVersionUID = 1L; public static final class MainValuesServiceException extends Exception { private static final long serialVersionUID = 1L; public MainValuesServiceException(final String message) { super(message); } } /** The log that is used by this service. */ private static Logger log = Logger.getLogger(AbstractMainValuesService.class); /** XPath that points to the river definition of the incoming request. */ /** XPath that points to the start definition of the incoming request. */ private static final String XPATH_START = "/art:mainvalues/art:start/text()"; /** The XPath that points to the end definition of the incoming request. */ private static final String XPATH_END = "/art:mainvalues/art:end/text()"; protected static final Document error(final String msg) { log.debug(msg); 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 static final River getRequestedRiver(final Document data, final String XPATH_RIVER) throws MainValuesServiceException { log.debug("MainValuesService.getRequestedRiver"); String riverStr = XMLUtils.xpathString(data, XPATH_RIVER, ArtifactNamespaceContext.INSTANCE); if (riverStr != null && (riverStr = riverStr.trim()).length() > 0) return RiverFactory.getRiver(riverStr); throw new MainValuesServiceException("no river found."); } protected static final Gauge getRequestedGauge(final Document data, final River river) throws MainValuesServiceException { final double[] minmax = getRequestedStartEnd(data, river); final Gauge gauge = river.determineRefGauge(minmax, CMP.compare(minmax[0], minmax[1]) != 0); if (gauge == null) throw new MainValuesServiceException("no gauge found."); return gauge; } /** * 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. */ public static double[] getRequestedStartEnd(final Document data, final River river) { log.debug("MainValuesService.getStartEnd"); final String startStr = XMLUtils.xpathString(data, XPATH_START, ArtifactNamespaceContext.INSTANCE); final String endStr = XMLUtils.xpathString(data, XPATH_END, ArtifactNamespaceContext.INSTANCE); if (startStr == null || endStr == null) { return river.determineMinMaxDistance(); } try { final double start = Double.parseDouble(startStr); final double end = Double.parseDouble(endStr); if (log.isDebugEnabled()) { log.debug("Found start: " + start); log.debug("Found end: " + end); } return new double[] { start, end }; } catch (final NumberFormatException nfe) { log.warn(nfe, nfe); return river.determineMinMaxDistance(); } } protected final Document buildDocument(final River river, final Gauge gauge, final List<MainValue> mainValues, final Object context) { log.debug("MainValuesService.buildDocument"); final Document doc = XMLUtils.newDocument(); final ElementCreator cr = new ElementCreator(doc, ArtifactNamespaceContext.NAMESPACE_URI, ArtifactNamespaceContext.NAMESPACE_PREFIX); final Element rootEl = cr.create("service"); cr.addAttr(rootEl, "name", "mainvalues"); doc.appendChild(rootEl); appendMetaInformation(doc, rootEl, river, gauge, context); appendMainValues(doc, rootEl, mainValues, river.getId(), 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. */ static void appendMetaInformation(final Document doc, final Element root, final River river, final Gauge gauge, final Object context) { log.debug("MainValuesService.appendMetaInformation"); final ElementCreator cr = new ElementCreator(doc, ArtifactNamespaceContext.NAMESPACE_URI, ArtifactNamespaceContext.NAMESPACE_PREFIX); final Range range = gauge.getRange(); final Element riverEl = cr.create("river"); cr.addAttr(riverEl, "name", river.getName()); final 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); } /** Checks i a main value has an official associated, */ private static boolean hasOfficialLine(final NamedMainValue nmv, final Integer riverId) { for (final OfficialLine ol : nmv.getOfficialLines()) { if (ol.getWstColumn().getWst().getRiver().getId().equals(riverId)) { return true; } } return false; } /** Append xml representation of main values to document. */ private void appendMainValues(final Document doc, final Element root, final List<MainValue> mainValues, final Integer riverId, final Object context) { log.debug("MainValuesService.appendMainValues"); final ElementCreator cr = new ElementCreator(doc, ArtifactNamespaceContext.NAMESPACE_URI, ArtifactNamespaceContext.NAMESPACE_PREFIX); final Element list = cr.create("mainvalues"); for (final MainValue mainValue : mainValues) { final Element newEl = buildMainValueElement(doc, mainValue, riverId, 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. */ private Element buildMainValueElement(final Document doc, final MainValue mainValue, final Integer riverId, final Object context) { final ElementCreator cr = new ElementCreator(doc, ArtifactNamespaceContext.NAMESPACE_URI, ArtifactNamespaceContext.NAMESPACE_PREFIX); final NamedMainValue namedMainValue = mainValue.getMainValue(); final MainValueType mainValueType = namedMainValue.getType(); final Element el = cr.create("mainvalue"); cr.addAttr(el, "value", mainValue.getValue().toString()); cr.addAttr(el, "name", namedMainValue.getName()); cr.addAttr(el, "type", mainValueType.getName()); if (mainValue.getTimeInterval() != null) { if (mainValue.getTimeInterval().getStartTime() != null) { cr.addAttr(el, "starttime", Long.toString(mainValue.getTimeInterval().getStartTime().getTime())); } if (mainValue.getTimeInterval().getStopTime() != null) { cr.addAttr(el, "stoptime", Long.toString(mainValue.getTimeInterval().getStopTime().getTime())); } } if (hasOfficialLine(namedMainValue, riverId)) { cr.addAttr(el, "official", "true"); } return el; } }