Mercurial > dive4elements > river
view flys-artifacts/src/main/java/de/intevation/flys/artifacts/services/MainValuesService.java @ 1072:80aecb01d79a
Let MainValuesArtifact have a state, outputmode and facet.
flys-artifacts/trunk@2556 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Felix Wolfsteller <felix.wolfsteller@intevation.de> |
---|---|
date | Wed, 24 Aug 2011 12:07:33 +0000 |
parents | a63d79107289 |
children | 26e19cdaed5e |
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 org.hibernate.Session; import de.intevation.artifacts.CallMeta; import de.intevation.artifacts.GlobalContext; import de.intevation.artifactdatabase.DefaultService; 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.backend.SessionHolder; 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 DefaultService { /** 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 process( 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]); 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()); } Session session = SessionHolder.acquire(); try { 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; } finally { session.close(); SessionHolder.release(); } } 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 :