teichmann@5863: /* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
teichmann@5863: * Software engineering by Intevation GmbH
teichmann@5863: *
teichmann@5994: * This file is Free Software under the GNU AGPL (>=v3)
teichmann@5863: * and comes with ABSOLUTELY NO WARRANTY! Check out the
teichmann@5994: * documentation coming with Dive4Elements River for details.
teichmann@5863: */
teichmann@5863:
teichmann@5831: package org.dive4elements.river.artifacts.services;
ingo@2599:
ingo@2599: import java.util.ArrayList;
ingo@2599: import java.util.List;
ingo@2599:
ingo@2599: import org.w3c.dom.Document;
ingo@2599: import org.w3c.dom.Element;
ingo@2599:
ingo@2599: import org.apache.log4j.Logger;
ingo@2599:
teichmann@5831: import org.dive4elements.artifacts.common.ArtifactNamespaceContext;
teichmann@5831: import org.dive4elements.artifacts.common.utils.XMLUtils;
teichmann@5831: import org.dive4elements.artifacts.common.utils.XMLUtils.ElementCreator;
ingo@2599:
teichmann@5831: import org.dive4elements.artifacts.CallMeta;
teichmann@5831: import org.dive4elements.artifacts.GlobalContext;
ingo@2599:
teichmann@5831: import org.dive4elements.river.model.Gauge;
teichmann@5831: import org.dive4elements.river.model.Range;
teichmann@5831: import org.dive4elements.river.model.River;
ingo@2599:
teichmann@5831: import org.dive4elements.river.artifacts.model.RiverFactory;
ingo@2599:
ingo@2599:
ingo@2599: /**
ingo@2599: * @author Ingo Weinzierl
ingo@2599: */
teichmann@5868: public class GaugeInfoService extends D4EService {
ingo@2599:
ingo@2599: interface Filter {
ingo@2599: boolean apply(Gauge gauge);
ingo@2599: }
ingo@2599:
ingo@2599:
sascha@3910: private static final class ReferenceNumberFilter implements Filter {
ingo@2599: private long refNr;
ingo@2599:
ingo@2599: public ReferenceNumberFilter(long refNr) {
ingo@2599: this.refNr = refNr;
ingo@2599: }
ingo@2599:
ingo@2599: @Override
ingo@2599: public boolean apply(Gauge gauge) {
teichmann@8202: if (log.isDebugEnabled()) {
teichmann@8202: log.debug("Test gauge '" + gauge.getName() + "'");
sascha@3910: }
ingo@2599:
sascha@3910: return gauge != null && gauge.getOfficialNumber() == refNr;
ingo@2599: }
ingo@2599: } // end of ReferenceNumberFilter class
ingo@2599:
ingo@2599:
teichmann@8202: /** The log that is used by this service.*/
teichmann@8202: private static Logger log = Logger.getLogger(GaugeInfoService.class);
ingo@2599:
ingo@2599:
ingo@2599: public static final String XPATH_RIVERNAME = "/art:river/@name";
ingo@2599:
ingo@2599: public static final String XPATH_REFERENCE_NR
ingo@2599: = "/art:river/art:filter/art:gauge/text()";
ingo@2599:
ingo@2599:
ingo@2599: public GaugeInfoService() {
ingo@2599: }
ingo@2599:
ingo@2599:
ingo@2599: @Override
ingo@2599: public Document doProcess(
ingo@2599: Document data,
ingo@2599: GlobalContext context,
ingo@2599: CallMeta callMeta
ingo@2599: ) {
teichmann@8202: log.debug("GaugeInfoService.process");
ingo@2599:
teichmann@8202: if (log.isDebugEnabled()) {
teichmann@8202: log.debug(XMLUtils.toString(data));
sascha@3557: }
ingo@2599:
ingo@2599: River river = getRiverFromRequest(data);
ingo@2599:
ingo@2599: List filters = getFilters(data);
ingo@2599: List allGauges = river.getGauges();
ingo@2599: List filtered = new ArrayList();
ingo@2599:
ingo@2599: for (Gauge g: allGauges) {
ingo@2599: for (Filter f: filters) {
ingo@2599: if (f.apply(g)) {
ingo@2599: filtered.add(g);
sascha@3557: break;
ingo@2599: }
ingo@2599: }
ingo@2599: }
ingo@2599:
ingo@2599: return buildInfoDocument(filtered);
ingo@2599: }
ingo@2599:
ingo@2599:
ingo@2599: protected River getRiverFromRequest(Document data) {
ingo@2599: String rivername = XMLUtils.xpathString(
ingo@2599: data,
ingo@2599: XPATH_RIVERNAME,
ingo@2599: ArtifactNamespaceContext.INSTANCE);
ingo@2599:
teichmann@8202: log.debug("Return Gauge info for River '" + rivername + "'");
ingo@2599:
ingo@2599: return rivername != null ? RiverFactory.getRiver(rivername) : null;
ingo@2599: }
ingo@2599:
ingo@2599:
ingo@2599: protected List getFilters(Document data) {
ingo@2599: List filters = new ArrayList();
ingo@2599:
ingo@2599: String refNr = XMLUtils.xpathString(
ingo@2599: data,
ingo@2599: XPATH_REFERENCE_NR,
ingo@2599: ArtifactNamespaceContext.INSTANCE);
ingo@2599:
ingo@2599: if (refNr != null && refNr.length() > 0) {
ingo@2599: try {
sascha@3910: filters.add(
sascha@3910: new ReferenceNumberFilter(Long.parseLong(refNr)));
ingo@2599: }
ingo@2599: catch (NumberFormatException nfe) {
teichmann@8202: log.warn(nfe, nfe);
ingo@2599: }
ingo@2599: }
ingo@2599:
ingo@2599: return filters;
ingo@2599: }
ingo@2599:
ingo@2599:
ingo@2599: protected Document buildInfoDocument(List gauges) {
ingo@2599: Document doc = XMLUtils.newDocument();
ingo@2599:
ingo@2599: ElementCreator cr = new ElementCreator(
ingo@2599: doc,
ingo@2599: ArtifactNamespaceContext.NAMESPACE_URI,
ingo@2599: ArtifactNamespaceContext.NAMESPACE_PREFIX);
ingo@2599:
ingo@2599: Element service = cr.create("service");
ingo@2599:
teichmann@8202: log.debug("Append " + gauges.size() + " gauges to info doc.");
ingo@2599:
ingo@2599: for (Gauge g: gauges) {
ingo@2599: Range r = g.getRange();
ingo@2599:
ingo@2599: Element el = cr.create("gauge");
ingo@2599: cr.addAttr(el, "name", g.getName());
ingo@2599: cr.addAttr(el, "lower", String.valueOf(r.getA().doubleValue()));
ingo@2599: cr.addAttr(el, "upper", String.valueOf(r.getB().doubleValue()));
ingo@2599:
ingo@2599: service.appendChild(el);
ingo@2599: }
ingo@2599:
ingo@2599: doc.appendChild(service);
ingo@2599:
ingo@2599: return doc;
ingo@2599: }
ingo@2599: }
ingo@2599: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :