ingo@2599: package de.intevation.flys.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: 
ingo@2599: import de.intevation.artifacts.common.ArtifactNamespaceContext;
ingo@2599: import de.intevation.artifacts.common.utils.XMLUtils;
ingo@2599: import de.intevation.artifacts.common.utils.XMLUtils.ElementCreator;
ingo@2599: 
ingo@2599: import de.intevation.artifacts.CallMeta;
ingo@2599: import de.intevation.artifacts.GlobalContext;
ingo@2599: 
ingo@2599: import de.intevation.flys.model.Gauge;
ingo@2599: import de.intevation.flys.model.Range;
ingo@2599: import de.intevation.flys.model.River;
ingo@2599: 
ingo@2599: import de.intevation.flys.artifacts.model.RiverFactory;
ingo@2599: 
ingo@2599: 
ingo@2599: /**
ingo@2599:  * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
ingo@2599:  */
ingo@2599: public class GaugeInfoService extends FLYSService {
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) {
sascha@3910:             if (logger.isDebugEnabled()) {
sascha@3910:                 logger.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: 
ingo@2599:     /** The logger that is used by this service.*/
ingo@2599:     private static Logger logger = 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:     ) {
ingo@2599:         logger.debug("GaugeInfoService.process");
ingo@2599: 
sascha@3557:         if (logger.isDebugEnabled()) {
sascha@3557:             logger.debug(XMLUtils.toString(data));
sascha@3557:         }
ingo@2599: 
ingo@2599:         River river = getRiverFromRequest(data);
ingo@2599: 
ingo@2599:         List<Filter> filters  = getFilters(data);
ingo@2599:         List<Gauge> allGauges = river.getGauges();
ingo@2599:         List<Gauge> filtered  = new ArrayList<Gauge>();
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: 
ingo@2599:         logger.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<Filter> getFilters(Document data) {
ingo@2599:         List<Filter> filters = new ArrayList<Filter>();
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) {
ingo@2599:                 logger.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<Gauge> 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: 
ingo@2599:         logger.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 :